org.hibernate.HibernateException: reassociated object has dirty collection reference

Hibernate JIRA | Steve Ash | 5 years ago
  1. 0

    We have a Parent class with @Id of type byte[] and a Child class also with @Id of type byte[]. There is a bidirectional @OneToMany relationship "List<Child> getChildren()" in Parent with Cascade.ALL and FetchType.EAGER. We load a parent (eagerly loading its children) and detach this instance from the session. We later want to re-attach the parent + children insteances by using the Lock API with LockMode.NONE. This fails with: {panel} 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(AbstractReassociateEventListener.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) at org.hibernate.impl.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2369) at com.argodata.fser.data.BlockManTest.testSimpleUpdate(BlockManTest.java:160) {panel} The problem is that {{ProxyVisitor}}'s {{isOwnerUnchanged}} uses id.equals( snapshot.getKey() ) to validate the the PersistentCollections snapshot owner id value is "equal" to the current id. For primitve keys like long and int this works, but for byte[] keys it fails as its a reference equals operation, not a value equals. If we switch our id type to long then we can re-attach the parent and children with the lock API as expected. Workaround is simple of course, just don't use array types for @Ids or wrap them with something that implements equals properly. However, considering that I believe primary arrays as keys are handled properly in other places, so I would guess that this is just an inconistency and that it should work as expected in ProxyVisitor as well. I will attach a TestCase replicating the problem shortly.

    Hibernate JIRA | 5 years ago | Steve Ash
    org.hibernate.HibernateException: reassociated object has dirty collection reference
  2. 0

    We have a Parent class with @Id of type byte[] and a Child class also with @Id of type byte[]. There is a bidirectional @OneToMany relationship "List<Child> getChildren()" in Parent with Cascade.ALL and FetchType.EAGER. We load a parent (eagerly loading its children) and detach this instance from the session. We later want to re-attach the parent + children insteances by using the Lock API with LockMode.NONE. This fails with: {panel} 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(AbstractReassociateEventListener.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) at org.hibernate.impl.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2369) at com.argodata.fser.data.BlockManTest.testSimpleUpdate(BlockManTest.java:160) {panel} The problem is that {{ProxyVisitor}}'s {{isOwnerUnchanged}} uses id.equals( snapshot.getKey() ) to validate the the PersistentCollections snapshot owner id value is "equal" to the current id. For primitve keys like long and int this works, but for byte[] keys it fails as its a reference equals operation, not a value equals. If we switch our id type to long then we can re-attach the parent and children with the lock API as expected. Workaround is simple of course, just don't use array types for @Ids or wrap them with something that implements equals properly. However, considering that I believe primary arrays as keys are handled properly in other places, so I would guess that this is just an inconistency and that it should work as expected in ProxyVisitor as well. I will attach a TestCase replicating the problem shortly.

    Hibernate JIRA | 5 years ago | Steve Ash
    org.hibernate.HibernateException: reassociated object has dirty collection reference
  3. 0

    HibernateException on session.buildLockRequest with byte[] as primary key

    Stack Overflow | 5 years ago | sheoran
    org.hibernate.HibernateException: reassociated object has dirty collection reference
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    Job scheduling issue 1.6.1

    GitHub | 3 years ago | ksa1983
    org.hibernate.HibernateException: reassociated object has dirty collection
  6. 0

    Duplicate visit bug

    GitHub | 5 years ago | beckyrobbins
    org.archiviststoolkit.mydomain.PersistenceException: failed to update, class: class org.archiviststoolkit.mydomain.DomainAccessObjectImpl object: [PATRON NAME REDACTED]

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. org.hibernate.HibernateException

      reassociated object has dirty collection reference

      at org.hibernate.event.def.OnLockVisitor.processCollection()
    2. Hibernate
      SessionImpl$LockRequestImpl.lock
      1. org.hibernate.event.def.OnLockVisitor.processCollection(OnLockVisitor.java:71)
      2. org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
      3. org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
      4. org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
      5. org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144)
      6. org.hibernate.event.def.AbstractReassociateEventListener.reassociate(AbstractReassociateEventListener.java:101)
      7. org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
      8. org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:774)
      9. org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:766)
      10. org.hibernate.impl.SessionImpl.access$600(SessionImpl.java:156)
      11. org.hibernate.impl.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2369)
      11 frames
    3. com.argodata.fser
      BlockManTest.testSimpleUpdate
      1. com.argodata.fser.data.BlockManTest.testSimpleUpdate(BlockManTest.java:160)
      1 frame