Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent NHibernate -- Saving Entity with Composite Key

First, I have the following table:

CREATE TABLE CustomerHub (
   CustomerId INT NOT NULL,
   HubId INT NOT NULL
)

Which I have mapped to the this entity:

public class CustomerHub
{
   public int CustomerId {get;set;}
   public int HubId {get;set}

   //GetHashCode, Equals, Etc...
}

Using this mapping:

public class CustomerHubMap : ClassMap<CustomerHub>
{
   UseCompositeId()
      .WithKeyProperty(x => x.CustomerId)
      .WithKeyProperty(x => x.HubId);
}

The problem I have is that when I create a new entity of type CustomerHub and attempt to save it, nothing is persisted to the database. I am able to retrieve everything fine, just not save them. For example:

//this will work
var x = session.CreateCriteria(typeof(CustomerHub)); 

//this will not
using (var trans = session.BeginTransaction()) 
{
   var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
   var y = session.SaveOrUpdate(custHub); 
   trans.Commit();
}

The odd part is that no exceptions are thrown, it simply just doesn't do anything. I fired up NH Profiler (excellent tool!) and it looks like it isn't issuing any type of insert command to the database.

Thoughts?

Note: I realize that this table looks much like a join table (because it technically is) and would best be served as a ManyToMany relationship on another entity such as Customer... but due to some extremely screwy data design (ie no Hub table) it is FAR simpler to map the join table to an entity and work with it that way.

like image 383
jckeyes Avatar asked Jul 27 '09 18:07

jckeyes


1 Answers

Edit (put at top)

quote from NHibernate docs:

Due to its inherent nature, entities that use this generator cannot be saved via the ISession's SaveOrUpdate() method. Instead you have to explicitly specify to NHibernate if the object should be saved or updated by calling either the Save() or Update() method of the ISession.

http://www.nhforge.org/doc/nh/en/index.html#mapping-declaration-id-assigned (5.1.4.7)

Composite ID have generator = assigned.

This goes back to composite id = sucking :)


You aren't issuing a flush or commit. You are probably used to working with something like identity that issues an INSERT on save, but composite are assigned by your code, not the database, so you need a flush/commit for the insert to take place.


var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
var y = session.SaveOrUpdate(custHub);
session.Flush();

or

using(var tx = session.BeginTransaction())
{
    var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
    var y = session.SaveOrUpdate(custHub);
    tx.Commit();
}

Also, one note: using composite keys will make you hate your life. A lot of things don't work the same with composite keys and it isn't immediately obvious. Basically NHibernate can do less of the work so you have to pick up the slack.

like image 132
anonymous Avatar answered Sep 19 '22 15:09

anonymous