Contents tagged with NHibernate

  • NHibernate Pitfalls: Deletes

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    While I was writing Deleting Entities in NHibernate, I noticed that actually it referred some pitfalls concerning deleting, so I decided to add them to the proper collection.

    There are several ways to delete entities in NHibernate, as you can see in the referenced post. The problems with each approach are:

    • Using Executable HQL: no cascade to related associations occurs, no events are raised;
    • Using Delete with an entity proxy: forces loading of all cascaded lazy associations before deleting; requires a Flush to apply changes (if it needs to be explicit or not depends on you flush settings);
    • Using Delete with a query string: all items are loaded into the session (not a single DELETE statement), no cascade occurs, no events are raised, no notification about the number of affected records and also requires a flush.

    Read more...

  • NHibernate Pitfalls: Get and Filters

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    This was suggested a long time ago by Kelly Brownsberger (@kbrowns). What happens is, even if you have filters defined, they are not applied on a call to ISession.Get<T>(). This is by design: you are explicitly asking for an entity with some id, so NHibernate just returns you that. On the other hand, static where restrictions defined at the entity level still apply.

    Read more...

  • NHibernate Pitfalls: Criteria and Collections of Non-Entities

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    Criteria API – and QueryOver, for that matter, which is just a strongly-typed wrapper around Criteria – cannot work with collections of non-entities: elements, components or dictionaries. If you need to work with those, you need to use one of the other APIs – LINQ, HQL or SQL.

    Read more...

  • Deleting Entities in NHibernate

    This post was motivated by a conversation with Salvador Gascon (@salvadorgascon). Might even go to the pitfalls section… Anyway, the problem is: how many ways there are to delete an entity in NHibernate? And what are the advantages/disadvantages of each?

    First, we have the classic one, using ISession.Delete(), which all NHibernate developers should be familiar with:

       1: var product = session.Get<Product>(id);
       2:  
       3: session.Delete(product);
       4:  
       5: session.Flush();

    Using ISession.Get<T>(), you force an entity – and all of its non-lazy associations and properties – to be loaded from the database. When you delete it, all associations marked for cascade delete will also be deleted.

    If you don’t want to load the entity from the database in order to delete it, you can use ISession.Load<T>(), for entities marked as lazy, this will return a proxy instead:

       1: var product = session.Load<Product>(id);
       2:  
       3: session.Delete(product);
       4:  
       5: session.Flush();

    Do note, however, that when Delete is called, the entity will still be loaded, as well as all its non-lazy associations. Flushing is required.

    For better performance, we can use Executable HQL:

       1: session.CreateQuery("delete from Product p where p.ProductId = :id")
       2: .SetParameter("id", id)
       3: .ExecuteUpdate();

    This will translate to a single plain old SQL DELETE command, so no entity will be loaded into the session. This has a big disadvantage, though: no cascade deletes will occur. This means that you may get exceptions due to foreign key violations. A good thing is that it returns the number of deleted records.

    Another way to delete is through an overload of the Delete method:

       1: session.Delete(String.Format("from Product p where p.ProductId = {0}", id));
       2:  
       3: session.Flush();

    In this case, we are providing the id in the query string, which is not good, mainly for performance reasons – with NHibernate HQL, SQL injections are much more difficult to do. A better alternative is to use positional parameters:

       1: session.Delete("from Product p where p.ProductId = ?", id, NHibernateUtil.Int32);

    In this case, together with the id, we also need to supply its type. Does not cascade nor return the number of deleted records.

    Read more...

  • NHibernate Pitfalls: HQL Delete Does Not Cascade

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    When you issue an HQL delete statement over an entity, you may be surprised to find out that it will not cascade to any configured associations it may have:

       1: session.CreateQuery("delete from Order o where o.Id = :id").SetParameter("id", 10).ExecuteUpdate();

    If you really want to cascade associations, you will have to load the entity explicitly and then call ISession.Delete() upon it.

    Read more...

  • NHibernate 4.0

    Recently, the NHibernate team released NH 4.0. You can get it as a NuGet package from https://www.nuget.org/packages/nhibernate, as a ZIP from http://sourceforge.net/projects/nhibernate/ or as source code from https://github.com/nhibernate/nhibernate-core. The full release notes are available at https://github.com/nhibernate/nhibernate-core/blob/master/releasenotes.txt, but here are some highlights.

    One of its most important features is that it no longer needs Iesi.Collections for most common uses: where you would declare a set as Iesi.Collections.Generic.ISet<T>, now you use System.Collections.Generic.ISet<T>. However, if you want to use the order-by attribute of sets, you still need Iesi.Collections, because NHibernate will still use it (LinkedHashSet<T>). All of the public APIs that used Iesi.Collections.Generic.ISet<T> or Iesi.Collections.ISet now use System.Collections.Generic.ISet<T>, this includes all the event handler methods.

    Method SaveOrUpdateCopy of ISession was removed and Merge should be used instead.

    The ManagedWebSessionContext context class was removed and the managed_web alias for XML configuration is no longer supported. Now you should use WebSessionContext and web.

    The Firebird driver was removed and replaced for FirebirdClientDriver. ASA10ClientDriver, ASAClientDriver and SQLiteDriver were removed in favor of SybaseSQLAnywhereDriver, SybaseAsaClientDriver and SQLite20Driver, respectively. A managed ODP.NET driver for Oracle is now available (OracleManagedDataClientDriver).

    Sql2012Dialect was introduced and now properly pages records. Also added Ingres9Dialect. SybaseASADialect (use SybaseSQLAnywhere10Dialect),

    MySQL now supports batching inserts (MySqlClientBatchingBatcher).

    There have also been some breaking changes in the IProjection interface because the IEnhancedProjection interface was removed and its methods moved to IProjection.

    Misspelled class AdoNetWithDistrubtedTransactionFactory is now AdoNetWithDistributedTransactionFactory.

    NHibernate XML configuration on App.config or Web.config now accepts attribute linqtohql.generatorsregistry.

    On mapping by code, you can now specify the class of a one-to-one endpoint (IOneToOneMapper.Class) and an optional table check clause (IClassMapper.Check). Also available are enhanced id generators Enhanced Sequence (Generators.EnhancedSequence) and Enhanced Table (Generators.EnhancedTable). You can now pass a dictionary to IGeneratorMapper.Params, no need to use anonymous types, which is better for dynamic code.

    QueryOver projections now support Math.Round() to round up floating point numbers.

    DefaultIfEmpty is now supported with GroupBy and Distinct is now supported with anonymous types.

    Finally, all static type fields in NHibernateUtil are now declared as their exact type, not a base class, which is better for using in mapping by code.

    Read more...

  • NHibernate Succinctly

    It’s with great pleasure that I see the release of NHibernate Succinctly, a book that I wrote for Syncfusion’s Succinctly series! It’s my second title, more to come! Winking smile

    Like Entity Framework Code First Succinctly, this book has something for the beginner as well as for more advanced users. Unlike EFCFS, it covers the current version of NHibernate.

    My good friend Zoran Maksimovic (@zoranmax) was the technical reviewer and besides him, I also want to thank everyone at Syncfusion: Hillary Bowling, Darren West, Tres Watkins and Graham High for their feedback and support, and for the opportunity they gave me. Of course, my coleagues at Critical, Pedro Gomes (@pedromvgomes) and Marco Carreira, and also my old friend Tiago Andrade, who also conducted reviews, cannot be forgotten as well!

    Go ahead, grab your copy and let me know what you think!

    By the way, it might be interesting to write something about my experience as an author… Any of you Succinctly authors out there would like to share your experience? Write me a line or comment here! Thanks!

    Read more...

  • NHibernate Pitfalls: XML Mappings

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    If you are still using XML mappings – .hbm.xml files –, there’s nothing wrong with that, but you may run into problems.

    First, you will need to add these files as embedded resources in your project, if you are calling Configuration.AddAssembly(), Configuration.AddClass() or you are specifying the name of the assembly in the .config file like this:

       1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
       2:     <session-factory>
       3:         <property name="connection.driver_class">NHibernate.Driver.Sql2008ClientDriver</property>
       4:         <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
       5:         <property name="connection.connection_string_name">MyConnection</property>
       6:         <mapping assembly="MyAssembly.MyModel" />
       7:     </session-factory>
       8: </hibernate-configuration>

    These methods will look for .hbm.xml files as embedded resources in that assembly:

    image

    Alternatively, you can have the files on the filesystem, but you will have to call Configuration.AddDirectory(), Configuration.AddFile() or Configuration.AddInputStream(), passing the appropriate parameters.

    In either case, the name of each .hbm.xml must end with .hbm.xml (of course!) and must be composed of the name of the associated class including its namespace.

    If you don’t do this, NHibernate will not find your mappings, which will result in runtime errors.

    Read more...