-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: a different object with the same identifier value was ...
PostPosted: Sun Mar 05, 2006 4:09 pm 
Newbie

Joined: Sat Feb 11, 2006 1:56 pm
Posts: 6
Hibernate version:
NHibernate 1.0.2.0

Reported Exception Message: {"a different object with the same identifier value was already associated with the session: 44, of class: BeautifulMinds.everythingsGreen.Core.Campaigns.CampaignerRealtimeData" }

Stack Trace: " at NHibernate.Impl.SessionImpl.CheckUniqueness(Key key, Object obj)\r\n at NHibernate.Impl.SessionImpl.DoUpdateMutable(Object obj, Object id, IClassPersister persister)\r\n at NHibernate.Impl.SessionImpl.DoUpdate(Object obj, Object id, IClassPersister persister)\r\n at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)\r\n at everythingsGreen.Customer.Tests.ActiveUserNonThreaded._Execute() in x:\\dotnet\\web\\everythingsgreen\\source\\everythingsgreen\\everythingsgreen.customer.tests\\singleclientontosingleclassthatpersistswithoutthreadingtest.cs:line 199" string

Detail:
I havent included all the requested pre-requisites for posting a message because I think the reason to my problem is more understanding other than anythingelse.

Everytime I need to hit the database in a for-loop, I acquire a session:
Code:
      private void CreateSession()
      {
         if(_session == null)
         {
            _session = _sessionFactory.OpenSession();
         }
         else
            _session.Reconnect();
      }


I either create a new one or reconnect.

I then get data attributes from multiple places and create an object named CampaignerRealtimeData - this object is to be persisted by NHibernate, and is a simple dumb-data-object with a primary key field.

The important issue here is that everytime the for-loop begins a cycle, attributes are acquired and a [b]new/[b] CampaignerRealtimeData object is created. This means I can logically do this:

Code:
for(int i = 0; i < _itemsToProcess; i++) {
   CampaignerRealtimeData data = GetRealtimeData();
   CreateSession();
   GetSession().SaveOrUpdate(data);
}

public CampaignerRealtimeData GetRealtimeData() {
   return new CampaignerRealtimeData(27, GetNumberOfVisits());
}


Here GetRealtimeData just returns the an object which always has the same primary key of 27, but GetNumberOfVisits will have changed - this obviously requires an update to the database.

The program I am building is a simulator for a real-life multithreaded enterprise system that receives data across communication channels such as TCP/IP, Email or some other mechanism. The data comes in, and a CampaignerRealtimeData object needs to be created so that it can then be persisted in the database. In this simplistic code it clearly doesnt make sense to keep creating what is essentially the same object. In the reallife situation, the time between calls could be days, and with other constraints I dont wish to cache the objects in memory. I want to keep the design simple, and this design works perfectly until I use it with NHibernate; I am positive its not NHibernate thats the problem but how I am using it.

If I dont use Reconnect/Disconnect and instead use OpenSession/Close, the code works, but I read that the former approach is much more efficient.

Thanks,

Nick.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 05, 2006 7:45 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
you've got the exception because you're creating different objects having the same id. the old object is not gc'ed because when you call save, nhibernate caches it. hibernate best coding practice sugest that when you construct an object its id should have the value used for unsaved objects. if you already have the id for the object, retrieve it from the db, change its properties then save it.
some thoughts:

1.if you already have the id of the object, you don't need to construct it in the loop again and again. construct it only once than do a
Code:
session.Update(data)

to reconect it with the session, in the loop, just update the property that changes.
2. to reconect the session at each iteration i think is highly inneficient.
On the other hand hibernate gurus stress that a session object is not thread nor exception safe.

HTH,
radu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 06, 2006 5:10 pm 
Newbie

Joined: Sat Feb 11, 2006 1:56 pm
Posts: 6
Radu,

Thanks for your response. I can see the reasoning behind the hibernate model, and I now understand why it is the way it is. Because the object is cached, I assume therefore that requesting to load my object will not result in a roundtirp to the DB? Maybe someone can offer some suggestions based on a design then...

I have some objects that model the business problem. I also have a database. The object model does not map to the database. I have an application level object/event processor that listens for a specific event with the object model. When this event occurs, its role is to collate some data together and make sure the event is persisted in the database. The event processor therefore gets data from the object model (think mediator pattern) and requests for the data to be stored by calling onto an interface:

Code:
_data.Store(campaignerID, RetrieCount, DateTime.Now);


_data is the implementation that deals with the persistence mechanism. Within this implementation I wish the data attributes passed in on the method signature to be persisted via Hibernate. To do this I created an object that is nothing but a data holder, and expected to just be able to persist the object.

I appreciate Hibernate is holding onto the object in its cache, so rather than creating this data holder wihtin the Store method so I can persist the object with Hibernate, I could load it assuming I dont involve a roundtrip to load the object (I want to avoid this because there is a heavy load on the system).

Any advice on this most welcomed.

Nick.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 08, 2006 3:23 pm 
Contributor
Contributor

Joined: Sun Jun 26, 2005 5:03 am
Posts: 51
Location: London, UK
Probably need a bit more context as to how your process is running. Is it a Windows service, hosted in a web app etc.

Reason is as mentioned, the Session object isn't thread-safe, but is relatively cheap to construct, the SessionFactory is the one you have to watch out for as it parses all the mapping files/determines the persisters to use etc.

_________________
Paul Hatcher
NHibernate Team


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 08, 2006 4:30 pm 
Newbie

Joined: Sat Feb 11, 2006 1:56 pm
Posts: 6
Hi Paul,

The application at the moment is just a DLL - a Test DLL. I have a second DLL with the domain model classes, and I have created a Customer Test DLL and I am trying to create a potential real-live scenario NUnit test. I intended to create a number of threads, and get them to all call onto the core application classes - thats where I started with this. However, being savvy I didnt overcomplicate the problem by setting off a whole bunch of threads - I just created one...I havent got this working still. In the final environment it is expected to be a web application, but I havent got that far yet. My idea was to get each thread to ask for its own session from the session factory, which I would expect to alleviate the non-threading issue, but I dont know. If it doesnt, got any advice?

Right now I am starting from scratch. I originally created some code that did all that I am trying to do now, not using threads and it seemed to work; I seem to have binned the code so I am going to create it again. I dont know if you saw the threading issue email I posted - I have a bizarre problem with the Thread.Sleep call being invoked on a thread - something requests an abort.

Anyway, thanks for the reply Paul, much appreciated.

Nick.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.