-->
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.  [ 2 posts ] 
Author Message
 Post subject: ClassCastException on flush when @PreUpdate handler bound
PostPosted: Thu Sep 08, 2016 10:39 am 
Newbie

Joined: Mon Feb 20, 2006 9:23 am
Posts: 9
I'm using Hibernate 5.1.1. The setup is as follows:

  • Two @Entity classes X and Y, with a 1-Many relationship from X to Y
  • A @PreUpdate callback method wired against X
  • A registered HibernateInterceptor

My failing test case simply creates a new instance of X, sets X.y to an appropriate Java collection value (e.g. new HashSet(), or new ArrayList()).

It then commits the instance via Hibernate. The error encountered is as follows:

Code:
java.lang.ClassCastException: java.util.HashSet cannot be cast to org.hibernate.collection.spi.PersistentCollection
   at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:39)
   at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
   at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
   at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
   at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:155)
   at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)
   at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
   at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
   at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)


After tracing through the code, here is my take on what is going wrong:

  • When the Session is flushed, DefaultFlushEntityListener.onFlushEntity() invokes the wrapCollections() method to turn my Java collection value into e.g. a PersistentBag. At this point the entity still contains an e.g. HashSet, but the Object[] values contains a PersistentBag.
  • Control is passed to DefaultFlushEntityListener.scheduleUpdate() and thence to handleInterception()
  • Finally we end up in JpaFlushEntityEventListener.invokeInterceptor() where, because there is a @PreUpdate registered for X, then calls copyState().
  • The copyState() overwrites the Object[] values using what is in the entity; hence we lose our PersistentBag, and it reverts to a plain Java collection e.g. HashSet.
  • Back in DefaultFlushEntityListener.onFlushEntity(), we call persister.setPropertyValues() to use the Object[] values array to update the entity. Because that array was overwritten above, we end up with the entity still containing a value for X.y of a HashSet.
  • Finally, when we reach FlushVisitor.processCollection(), an attempt is made to case the collection value (still a HashSet) to a PersistentCollection. At which point the ClassCastException occurs.

If I remove the @PreUpdate annotation, then the save completes without error. Hence it appears that the presence of the annotation, along with a registered Interceptor, causes any wrapped collections to be "unwrapped" before the flush executes.

I'd be grateful if someone could verify the above to confirm whether this is a bug or I am doing something wrong. In any case, if I wanted to both preserve my Interceptor and @PreUpdate callback, is there anything I can do to work around this?

Thanks

Alan


Top
 Profile  
 
 Post subject: Re: ClassCastException on flush when @PreUpdate handler bound
PostPosted: Thu Sep 08, 2016 11:20 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
That sounds like a bug. Please provide a replicating test case and open a Jira issue.


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