Oliver
Oliver

Reputation: 11597

Cloning an entity in NHibernate?

I want to save a single object to the database twice. I have this code:

using (var ss = NHibHelp.OpenSession())
using (var tt = ss.BeginTransaction())
{
    var entity = new Entity();

    ss.Save(entity);
    ss.Save(entity);

    tt.Commit();
}

But this results in only one row being added to the database. How do I insert a single object into the database twice (with two different Ids) ?

Upvotes: 3

Views: 3751

Answers (2)

Mr Mush
Mr Mush

Reputation: 1538

You can do it in two ways:

  1. Clone the entity, should be a deep copy.

    using (var ss = NHibHelp.OpenSession())
    using (var tt = ss.BeginTransaction())
    {
      var entity = new Entity();
      var clonedEntity = entity.Clone();
      ss.Save(entity);
      ss.Save(clonedEntity);
    
      tt.Commit();
    }
    

If your ID is assigned, remember to create a new ID. Deep copy have some issues with complex entities, if you have inverted collection you need to re-reference them.

2.Open a second transaction in a new session and commit it.

var entity = new Entity();
using (var ss = NHibHelp.OpenSession())
using (var tt = ss.BeginTransaction())
{      
     ss.Save(entity);

     tt.Commit();
}

using (var ss = NHibHelp.OpenSession())
using (var tt = ss.BeginTransaction())
{      
     ss.Save(entity);

     tt.Commit();
}

Upvotes: 3

Martin Ernst
Martin Ernst

Reputation: 5679

You shouldn't do this - NHibernate maintains "object identity" within it's session, so it will not differentiate between ..well.. the same object. I would really advise against this, and a better solution would be to look at a way of cloning the object (either via reflection, or a Clone method), and then saving the cloned object.

If you want to ignore my advice above, you can get it to work by evicting the entity from the session, setting it's id back to it's unsaved value (depends on your mapping, but probably 0), and then saving it again.

It might also work if you just called session.Merge(entity) twice (you probably have to reset the id to it's unsaved value after the first call).

Alternatively you could use a stateless session with session.Merge() and then you don't have to evict the entity between Save's.

Upvotes: 7

Related Questions