-->
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.  [ 12 posts ] 
Author Message
 Post subject: Session.contains() always returns false
PostPosted: Wed Nov 10, 2004 11:06 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
Hibernate version: 2.1.6

I am having a hard time with those NonUniqueObjectExceptions.

I have a detached object instance that I want to reattach. In some cases there's already another instance of the object in the current session, so that I get the NonUniqueObjectException. That's quite correct behaviour.

Unfortunately I did not find any way how to check whether the another instance of the detached object is already present in the cache, because session.contains() always returns false.

I debugged into this and found out that contains() does the following:

Code:
return entityEntries.containsKey(object);


Finally this ends in HashMap.containsKey(), which calls HashMap.hash(), which calls HashMap$IdentityKey.hashCode().

And here's the real problem:
Code:
public int hashCode() {
   return System.identityHashCode(key);
}


This method calls identityHashCode, which totally omits any hashCode() implementation in my Hibernate persisted beans. Thus session.contains() will always return false, except if the detached object and the instance that is contained in the session have the same identityHashCode, which is impossible.

Maybe I am wrong, but isn't this a major problem with the Hibernate implementation.....


Top
 Profile  
 
 Post subject: Samesame
PostPosted: Thu Nov 11, 2004 8:11 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
Got the same problem over here...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 11, 2004 8:18 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Use session.saveOrUpdateCopy(). Unfortunately, it does't work properly with cascading (known issue in JIRA) in Hibernate 2.1.x.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Fix?
PostPosted: Thu Nov 11, 2004 10:04 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
Is the Session.contains() impl. desireable or even intentional?
Should it be regarded as a bug?

Finland in December?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 11, 2004 10:08 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
File a bug report.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Okay
PostPosted: Thu Nov 11, 2004 10:10 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
Will file a report.

See you in Helsinki (Finland) in December?



Regards
/JVK


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 11, 2004 10:11 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Forget that, its not a bug. The comparision uses the identifiers to find out if an object already exists in a Session. Thats nothing you could override in your domain classes.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: ?
PostPosted: Thu Nov 11, 2004 10:22 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
Doesn't work.

flow:

Session session = SessionFactory.createSession();
Object X = session.get(PersistentPOJO.class,new Long(1));
session.close();
session = SessionFactory.createSession();
Object Y = session.get(PersistentPOJO.class,new Long(1));
session.lock(X); //No way dude

if(session.contains(X)) //returns false although it shouldn't
session.lock(X);
session.close();


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 11, 2004 11:33 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
It is a detached object, hence it is not "in" the session. The semantics are quite correct and natural.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 12, 2004 4:30 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
X and Y are 2 instances of the same row in the table.
Therefor it would make sense to do an equals() comparison in contains().

Otherwise the problem becomes that you have to lock() _all_ detached objects at the beginning of every request (if you're down with the session-per-request-with-detached-objects"-style). The you have to centralize references to all detached object, because if you try to lock a detached object after doing any kind of retrieval, you'll be sure to be in trouble.

I can understand that you want to be able to do identity-comparison, but the problem is that in my example, X and Y ARE the very same object, and Hibernate doesn't take that into consideration, even though I've specified compareTo(), equals() and hashCode().

Is there any other possible solution to this dilemma that I've overseen?


Top
 Profile  
 
 Post subject: Suggestion
PostPosted: Fri Nov 12, 2004 5:08 am 
Newbie

Joined: Thu Nov 11, 2004 7:43 am
Posts: 6
IOn my example, Having X as a detached instance, and Y as a persistant instance of the same database row, wouldn't

x = s.lock(x,LockMode.NONE);

be a much better solution?

then s.lock(Object o, LockMode mode)
would do first an identifier-lookup (see if the 1st level cache contains a persistent object with getClass() == o.getClass() && id.equals(o.getId()),
then do a persistentObjectInCache.equals(o), and if it returns true, it'd return a reference to the persistent object, else, do the normal locking and return a reference to o.

That'd be much better sinch saveOrUpdateCopy() doesn't work with cascading.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 12, 2004 9:49 am 
Beginner
Beginner

Joined: Tue Aug 17, 2004 5:06 am
Posts: 46
I'm having the same problem with the session-per-request pattern.

There are always detached objects from the last session and I can't update them because there might already be another instance of it in the current session.

I did not find any way to determine if there's already such other instance in the session. Session.contains() is quite useless for this.

We would need something like session.containsObjectWithId(Class, Id).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 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.