| I am in the process of migrating from Hibernate ORM 5.2 to 5.3. Maybe we did something wrong over the last 8 or so years, but starting with Hibernate 5.3, so most basic function fails: Session.save(..) does this:
java.lang.ClassCastException: class org.hibernate.action.internal.DelayedPostInsertIdentifier cannot be cast to class java.lang.Integer (org.hibernate.action.internal.DelayedPostInsertIdentifier is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
at org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap(IntegerTypeDescriptor.java:19)
at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$1.doBind(IntegerTypeDescriptor.java:46)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:74)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39)
at org.hibernate.type.EntityType.nullSafeSet(EntityType.java:280)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2868)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2843)
at org.hibernate.persister.entity.AbstractEntityPersister$4.bindValues(AbstractEntityPersister.java:3064)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:41)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3072)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3663)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.executeInserts(ActionQueue.java:461)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:359)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:131)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:709)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:696)
It happens when auto-generating an ID based on table identity. The model has this id attribute:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
I could track it down to a change in behavior in AbstractSaveEventListener.performSaveOrReplicate(...): In Hibernate ORM 5.2, requiresImmediateIdAccess was false, inTxn was true. This resulted in shouldDelayIdentityInserts to be false. Since Hibernate ORM 5.3, shouldDelayIdentityInserts is true, because the new code also checks the FlushMode in shouldDelayIdentityInserts(...) which is always FlushMode.COMMIT in our code. Previously, Hibernate ORM was smart enough to notice that Session.save(..) together with an autogenerated IDENTITY ID needs an immediate, non-delayed database insert. But anyway, I don't know why Hibernate even tries to put an instance of DelayedPostInsertIdentifier into an IntegerTypeDescriptor. So, is this even a bug in Hibernate or did we do something wrong over all these years? |