1

I have a user and credit_card entity, user has a collection of credit_card. The primary key for both of these entities i have is a byte[].

First session: - I opened a new session. - Do criteria query on the users table, which actually goes to the DB and fetches user + credit_cards and finally i have a user Object say userObj. - Close the session.

Second session: - I Opened another session. - trying to invoke session.buildLockRequest(LockOptions.NONE).lock(userObj);

Now hibernate will try to reattach the detached object, but i get following error:

org.hibernate.HibernateException: reassociated object has dirty collection reference
at org.hibernate.event.def.OnLockVisitor.processCollection(OnLockVisitor.java:71)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144)
at org.hibernate.event.def.AbstractReassociateEventListener.reassociate(AbstractReassociateEve    ntListener.java:101)
at   org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.access$600(SessionImpl.java:156)

I tried to debug it in the hibernate code, and found out, that hibernate tries to check if the passed object's collection (credit_cards) is actually owned by user (which is user1).

So somewhere deep down the code in hibernate, it seems like it is checking for the equality with equals method of the primary keys of the passed object (which is user1) and another object what it is calling a snapshot object. Since byte[] is essentially an array and fails on equals check and throw the above error. I know i can do above work in just one session, but this is just a scenario.

I tried using Long/Integer as a primary key and it works just fine, since it passes the equality check.

Hibernate version : 3.6.9.Final (i tried to take a look at the 4.1.1.Final version as well, but files/code which throws this error are not changed) DB : SQL server

Is it a issue in hibernate or i am doing anything wrong ?

sheoran
  • 11
  • 2
  • My colleague has reported this as a bug on hibernate: [https://hibernate.onjira.com/browse/HHH-7180](https://hibernate.onjira.com/browse/HHH-7180) – sheoran Mar 15 '12 at 18:04

2 Answers2

1

use a String instead of a byte[] as primary key. it can carry same value and will pass the equals method

String myId = new String(bytes);

myId.getBytes();

it is not an hibernate issue.

Roman K
  • 3,309
  • 1
  • 33
  • 49
  • Yes, i tried that and it is working fine if i use Long, but is there any solution of this problem with using byte[] as primary key? – sheoran Mar 15 '12 at 15:12
1

It's not an issue in Hibernate. The class of the ID must implement hashCode and equals properly. byte[] doesn't, so it's not a valid ID class. Using a byte[] as an ID is, IMO, a really bad idea. A Long is a really better idea. If you really want to keep your byte array, then wrap it into a custom type, or transform it into a String using Base64 or Hex encoding.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I agree and i know using byte[] may not be the best practice. But my question is why byte[] is not supported for this kind of situations, or is there any list of non-supported/non-recommended types from hibernate ? – sheoran Mar 15 '12 at 16:00
  • The ID class must implement equals and hashCode properly. That is the rule. Two different instances representing the same value in database must be equal, and have the same hashCode. – JB Nizet Mar 15 '12 at 16:04