Contents tagged with NHibernate

  • Joining Orchard part records in HQL

    In yesterday’s post, I showed the basics of HQL querying in Orchard. It is by far the most flexible way to  query Orchard’s database, but one thing I didn’t show is how this works in relation to Orchard’s content type system. Querying over records is nice, but if those records are part records, you need to be really careful and check that they correspond to a real content item, that his content hasn’t been archived, and that its publication state is what you need it to be. In order to do that, you’ll have to join with ContentItemRecord and ContentItemVersionRecord. But how do you express joins in HQL in a way that works with Orchard records?

    Read more...

  • Querying Orchard in HQL

    Orchard has two APIs on IContentManager to query content items: Query, and HqlQuery. Query is the older API, but it’s also the simplest. It’s great when you want to perform a simple query such as “get all content items with part TitlePart where the title begins with A”. HqlQuery is a little more advanced, closer to nHibernate APIs, and allows for more complex queries. It was added to build the dynamic queries necessary for Projections. It is still, however, designed around the Orchard content type system, which makes it inadequate for queries that don’t trivially map to content items and parts.

    Read more...

  • Storing non-content data in Orchard

    Dry earthA CMS like Orchard is, by definition, designed to store content. What differentiates content from other kinds of data is rather subtle. The way I would describe it is by saying that if you would put each instance of a kind of data on its own web page, if it would make sense to add comments to it, or tags, or ratings, then it is content and you can store it in Orchard using all the convenient composition options that it offers. Otherwise, it probably isn't and you can store it using somewhat simpler means that I will now describe.

    Read more...

  • Orchard 0.5 is out

    (c) Bertrand Le Roy 2004 Before I joined Microsoft seven years ago, I had spent a couple of years building a Web CMS. It wasn’t open-source unfortunately but the experience convinced me that most public-facing web sites would shortly use some form of CMS. I also forged strong opinions about the right level of component granularity that a CMS must implement.

    Read more...

  • A total n00b’s guide to migrating from a custom data layer to Nhibernate: so many choices

    (c) Bertrand Le Roy 2005 One of the great things about NHibernate is its vibrant community and ecosystem. So many people are using it or building other libraries on top of it that you can be pretty sure that there is always a reasonable solution to any problem you might face. Or several.

    This means of course that there are lots of choices you can make about how you use NHibernate. While this is essentially a good thing, too many choices can be intimidating when starting to use a technology.

    In this post, I’ll present some of the first choices you are going to have to make for your NHibernate code. I’ll explain the choices that our team made for our own migration and an attempt at explaining why you would make different choices depending on the particular context of your application.

    1. Database first or object first?

    That’s an easy one.

    If you already have a database, it’s database first.

    If you already have both, all you have to do is build the mappings.

    If you already have an object model, it depends how much you care about the shape of your database. NHibernate has reasonable defaults so you might be able to get away with object first and reasonably fuzzy mappings (or even a generated mapping). The obvious advantage of that approach is that you’ll be able to easily move database engines without having to rewrite anything but your web.config.

    If you need more control over the shape of the database, you might be able to achieve just that by making your mappings more explicit but still keep generation of the database from NHibernate.

    If that’s still not enough control, just don’t generate the database, and instead manually maintain database, objects and mappings.

    In our own project, we had the database already, but we want to abstract ourselves of a particular engine eventually, so we are moving from a database first approach to an object first approach. Extensions to the application will have to work independently of the database engine (because the app itself is), so it will have to be object first for them.

    2. To lazy-load or not to lazy-load?

    Lazy loading is the practice of delaying the loading of an object until the moment when it is actually used for the first time. If you have a collection of blog post objects for example, and those objects each have a property that is their collection of comments, you won’t want those comments to be queried from the database unless you are actually going to use them.

    Lazy loading is obviously a good thing, but you also must know that it can get you in trouble. So it can be a dangerous tool, but its usefulness far outweighs the danger.

    I’ve also mentioned in the previous post that lazy loading requires the use of dynamic proxies and that these in turn require that you run in higher trust than medium. Well, several commenters pointed out that this isn’t exactly true.

    Lazy loading of collection properties does not require the generation of dynamic proxies at all because NHibernate can set the value of those properties directly to a list type that already implements lazy loading. It is only in the case of lazy loading of properties or 1-1 associations that the proxy generation will be necessary. In other words, if your database schema only has 1-N and N-N associations or if you don’t mind eager loading on your 1-1’s, NHibernate can run in medium trust with no problem. This is the approach we are currently using in our application. We will revise it if necessary.

    The first way to achieve medium trust lazy-loading is to generate the proxies at build-time instead of dynamically at runtime. Caveat with this approach is that the generated proxies will be specialized to a dialect, which might or might not be a problem. You may be able to mitigate that problem by building dialect-specific versions for all databases that you target, but this is definitely less convenient than the entirely dynamic approach.

    The second approach is to fix the code of the proxy factory that you are using to work in medium trust, which is entirely achievable but clearly not for n00bs. Apparently patches are on their way here and this could make the whole problem go away in the near future.

    And the last and lamest approach is to disable lazy loading entirely.

    3. What dynamic proxy factory to use?

    Once you’ve decided that you’re going to use lazy loading and are going to need dynamic proxies, you still have to decide which proxy factory you’re going to use. Three choices are available out of the box: Castle, LinFu and Spring.

    If you want to work with Castle.ActiveRecord or Castle.Windsor, Castle is the obvious choice.

    If you want to work with Spring, Spring is obviously what you should use.

    If you are not using Castle or Spring, or have no idea what you want, LinFu can be a reasonable default.

    In our application, because we don’t need dynamic proxies for the moment, we haven’t had to choose.

    3. XML, attributes or fluent mappings?

    XML

    XML mappings are the default but some people dislike XML’s verbosity. There is also a fair amount of repetition and magic strings involved. Refactoring won’t propagate automatically to the mapping files. Advantages include that it’s the most mature approach and that it doesn’t require any additional dependency.

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        namespace="Nhib.Models" assembly="Nhib">
    
      <class name="Product" table="Products">
        <id name="SKU">
          <generator class="uuid.hex" />
        </id>
        <property name="ProductName"/>
        <property name="BasePrice" />
      </class>
    
    </hibernate-mapping>
    Attributes

    It is possible to use attributes through Castle to specify the mappings instead. This is very easy, involves minimal repetition and a less magic strings than XML. On the other hand, doing the mapping on the objects themselves means less separation of concerns as the objects and the mappings are in the same place. It also means buying into the whole active record approach and giving up POCOs.

    [ActiveRecord("Products")]
    public class Product : ActiveRecordBase {
        [PrimaryKey(PrimaryKeyType.UuidHex)]
        public string SKU { get; set; }
        [Property]
        public string ProductName { get; set; }
        [Property]
        public double Price { get; set; }
    }
    Update: Gauthier Segay pointed out that it's not exactly true that you have buy into the whole Castle active record approach. More info here: 

    http://www.castleproject.org/activerecord/documentation/trunk/advanced/mediator.html

    Fluent

    Finally, the favorite approach du jour is Fluent NHibernate. That approach still keeps mappings nicely separated but has several other advantages.

    First, it’s code, which opens up a lot of dynamic scenarios.

    Second, it’s strongly-typed. That means that refactoring will work, that you will get compile-time checks and IntelliSense.

    Third, it uses Lambdas and a fluent interface, and those are so cute… On the other hand, if you find those alien, it might not be such a win. On the other other hand, it’s a good occasion to learn something new and cool.

    public class ProductMap : ClassMap<Product> {
        public ProductMap() {
            Id(p => p.SKU).GeneratedBy.UuidHex("B");
            Map(p => p.ProductName);
            Map(p => p.Price);
        }
    }

    In our application, we have chosen XML mappings for now to minimize the number of dependencies and because choosing the most mature approach also means learning is more incremental. We might revise that decision if and when the disadvantages become too much of a problem and as we learn more.

    4. HQL, criteria, lambdas, ActiveRecord or Linq?

    HQL

    HQL is the Hibernate Query Language and is the default way of querying in NHibernate. It works and is mature but it is a text format, which means no static verification, refactoring or IntelliSense.

    “select p from Product as p where p.ProductName like 'boot%'”

    There are a few alternatives to HQL though. Let’s first talk about native SQL. It is possible to send native SQL from NHibernate but you should really only do that if you need to use a specific native feature of your database. While the possibility exists, it is not a relevant choice here.

    CreateCriteria

    The NHibernate session object has a CreateCriteria method that exposes a fluent querying interface. You can use it with expressions, but this is deprecated, or you can use it with restrictions, which are very similar but more current.

    session.CreateCriteria<Product>()
    .Add(Restrictions.Like("ProductName", "boot%");

    This API tends to be relatively verbose and is not completely strongly typed but it may be more appropriate than HQL for simple queries.

    Lambdas

    The nhlambdaextensions project provides a strongly-typed alternative to the restrictions described above through the use of Lambda expressions. This is a strong choice that comes close to Linq but it does require yet another dependency.

    session.CreateCriteria<Product>()
    .Add<Product>(p =>
    p.ProductName.StartsWith("boot",
    StringComparison.CurrentCultureIgnoreCase));
    ActiveRecord

    If you chose to use Castle ActiveRecord, you can still query using HQL, but you also get basic repository-like operations directly on your data classes out of the box.

    FindAll(typeof(Product), Restrictions.Like("ProductName", "boot%"));
    Linq

    Finally, you can use an implementation of Linq to query NHibernate. This is Linq, for NHibernate. In other words, pure, distilled WIN: strong typing, compile-time checks, etc. The problem is that it is still a work in progress (and an additional dependency).

    from product in session.Linq<Product>()
        where product.startsWith("boot",
    StringComparison.CurrentCultureIgnoreCase) select product;

    Linq to NHibernate can be obtained from NHibernate Contrib or as part of Fluent NHibernate.

    For the moment, our application uses CreateCriteria with restrictions for simple queries, and HQL in places. Again, the motivation here is to minimize the dependencies.

    Conclusion

    I hope this post will be helpful for NHibernate beginners such as myself to make the right first choices.

    Next time, we’ll really start digging into our transition from our old custom data layer.

    Read more...

  • A total n00b’s guide to migrating from a custom data layer to Nhibernate: getting started

    (c) Bertrand Le Roy 2003(Screencast can be found at the end of the post)

    To be clear when I say “total n00b”, I’m not talking about you, dear reader, I’m talking about me. The last time I wrote any serious data access code was circa 2002. Since then, I got hired by the Evil Empire and started developing new tools to make it easier to build demos of Northwind master-details. I jest, I jest. Or do I?

    So let me explain what I’m going to talk about in this and future related blog posts. We have this e-commerce application that Rob started and that we’re going to continue developing. Last time Rob touched the data access, he wanted to experiment with going back to less abstraction and to working directly with that interesting data-centric Domain Specific Language, you know, SQL. So he went ahead and played with that T4-driven DAL generator. It was interesting as an experiment, and Rob’s blog series is all about experimenting publicly, but let’s face it, that data access didn’t fly much farther than that. To be clear, I’m not saying that Rob was to blame for our sucky data access layer, but the truth is that we have had this franken-DAL from the nineties in the code for a few months now and it needs replacing. So what do we do?

    First, we look around and find out what other people out there are doing. We could go for the Microsoft flavor of ORM, EF, but we’re not going to do that (at least not yet) and will instead go for the one that is the most widely used by the community as of today, and that is, I believe, NHibernate. The home page for the project itself can be found at http://nhforge.org and the best place to get started is probably the tutorial section of that site: http://nhforge.org/doc/nh/en/index.html#quickstart.

    In this first post, I’ll just play with the library and try to get a list of products to display on a page. In future posts, I’ll look at the actual app and start migrating it. For this time, because I’m just trying to get to grips with a library I don’t know, it’s going to be quick and it’s going to be dirty. Definitely don’t take any of what you are about to see as best practices. Ever.

    The first step is to add the NHibernate and dependencies to the project. The library can be downloaded from SourceForge (http://sourceforge.net/projects/nhibernate). Nhibernate is itself under LGPL but it comes with the following dependencies:

    You may not care too much about that, but your boss and his lawyer might… Technically, all you need to add to the project is a reference to the NHibernate dll and the others will follow.

    Once the reference has been added to our project, we can start configuring. This can be done in a variety of manners but the easiest is to do it through web.config. The basic configuration for NHibernate consists in the connection string, the SQL dialect and the proxy factory to use. Because we don’t want to repeat ourselves and because I prefer my connection strings to live in the connection strings section of web.config, I’ll use a “connection.connection_string_name” setting instead of a “connection.connection_string” setting:

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
      <session-factory>
        <property name="connection.connection_string_name">
    KonaConnectionString
    </property> <property name="dialect">
    NHibernate.Dialect.MsSql2000Dialect
    </property> <property name="proxyfactory.factory_class">
    NHibernate.ByteCode.LinFu.ProxyFactoryFactory,
    NHibernate.ByteCode.LinFu
    </property> </session-factory> </hibernate-configuration>

    The proxy factory factory class stuff looks a little intimidating and a little over-architected from just looking at it (a factory factory? To create proxies?) but it’s not as bad as it looks. What this is doing is declaring what library to use to generate dynamic proxies for our data classes. It is a good thing that NHibernate is open to multiple providers here, and the good news is this is probably the first and last time you need to know about this. Just make a choice if you care (and know why you care), or use this one (licensed under LGPL) if you don’t.

    But what is a dynamic proxy, you may ask? First and foremost, it is a proxy class that will be used in place of the POCO class that you will provide to represent your data. Its purpose is to intercept all calls into the object’s properties, both getters and setters, and to handle things like lazy loading. The dynamic aspect of it is that those proxy classes are dynamically generated, usually using Reflection.Emit. This means that until .NET 4.0 is here, using lazy loading in NHibernate will prevent the application from running in medium trust. More on that in future posts, but know that lazy loading is not mandatory and can easily be disabled from the mapping file.

    The next thing to do is to grab the NHibernate configuration in order to create a session out of it. The configuration can be built from the web.config data like this:

    var nhconfig = new NHibernate.Cfg.Configuration().Configure();

    A session is the mediator between your code and Nhibernate. According to the documentation, it is a “short-lived object representing a conversation between the application and the persistent store”. Its lifetime is usually the same as the lifetime of the request. Here’s how you can create a session:

    var session = nhconfig.BuildSessionFactory().OpenSession();

    With all that we are pretty much set-up but we are still lacking any data. Let’s fix that and attempt our first mapping. I’m going to use a simplified version of the product database we have in the commerce app (which is none other than AdventureWorks). In there, I have a Products table that looks like this:

    Products Table

    We don’t have to map everything in that table so we won’t (yet). Instead, we’ll create a simple and incomplete class to represent a product:

    public class Product {
        public virtual string Sku { get; set; }
        public virtual Guid SiteID { get; set; }
        public virtual string Name { get; set; }
        public virtual double BasePrice { get; set; }
    }

    Notice how all fields are virtual here. This, again, is done so that a dynamic proxy class that overrides those properties can be created.

    Now we have the O (object) and the R (relational), so let’s do the M. The mapping is an XML file that we’ll put next to our Product class:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        namespace="Nhib.Models" assembly="Nhib">
    
      <class name="Product" table="Products">
        <id name="Sku">
          <column name="SKU" sql-type="nvarchar(50)" not-null="true"/>
          <generator class="uuid.hex" />
        </id>
    
        <property name="SiteID"/>
        <property name="Name">
          <column name="ProductName"/>
        </property>
        <property name="BasePrice" />
      </class>
    
    </hibernate-mapping>

    The mapping class is named like the Product class, with a “.hbm.xml” extension. It is also configured to build as an embedded resource so that Hibernate can reflect on it at runtime. This is done by setting the Build Action in the properties of the file in Project Explorer:

    EmbeddedResource

    And we’re done as far as setup is concerned. Now all that remains to do is to actually query and display that data.

    Because I’m just playing with the framework at this point, I’ll just query from the Index controller action:

    var nhconfig = new NHibernate.Cfg.Configuration().Configure();
    nhconfig.AddClass(typeof(Product));
    using (var session = nhconfig.BuildSessionFactory().OpenSession()) {
        var query = session.CreateQuery("select p from Product as p");
        ViewData.Model = query.List<Product>();
    }

    UPDATE: Ayende is right to attract my attention to the fact that building a session factory is an expensive operation and so you should treat it as a singleton. In other words, create the factory once and store it in a static variable. For the sake of the simplicity of the example, I'm leaving the code above, but again, don't do this at home... 

    And finally, let’s render this from the view:

    <ul>
    <% foreach (var p in Model) { %>
        <li><%= Html.Encode(p.Name) %> - $<%= p.BasePrice %></li>
    <% } %>
    </ul>
    

    The results look like this:

    Product rendering

     

    I hope this gives a good idea of how simple it is to get started with NHibernate, because it really is. I knew near to nothing about it and almost didn’t have to fight the framework to get it running. Seeing the first successful rendering on my very first CTRL+F5 was very encouraging.

    In a future post, I’ll show how this applies to a real-world application and how we migrated such an application from its existing data layer to one that uses NHibernate.

    The source code can be downloaded from here: NHibGettingStarted.zip (warning: all files provided under their respective licenses).

    … and here’s the screencast:

    Read more...