CompositeId, when the id assigned by PrePersist method an HibernateException: identifier of an instance of _ was altered is thrown
Description
I have some legacy code that I'm working with and uses composite-id for some entities, I have also custom IdGenerator for the one of id.
The generator generates the id correctly, but during flush operation hibernate throws following exception:
Caused by: org.hibernate.HibernateException: identifier of an instance of some.company.modules.model.ModelY was altered from CompositeId: code='WT1' | revision='0' to CompositeId: code='null' | revision='0' at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:98) at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:182) at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:141) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:234) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:79) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1411) at org.hibernate.query.sql.internal.NativeQueryImpl.prepareForExecution(NativeQueryImpl.java:601) at org.hibernate.query.spi.AbstractSelectionQuery.beforeQuery(AbstractSelectionQuery.java:452) at org.hibernate.query.spi.AbstractSelectionQuery.beforeQueryHandlingFetchProfiles(AbstractSelectionQuery.java:439) at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:420) at org.hibernate.query.Query.getResultList(Query.java:120)
Flush is forced by HQL query checking if new generated code does not exist in database (Query.getResultList). It looks like the problem is in ‘AbstractSaveEventListener::performSave'. This method does not support ‘CompositeNestedGeneratedValueGenerator’. Please see attachment.
Exception occurs since 6.3.x version. 6.2.x and earlier versions works fine.
Attachments
1
Activity
Show:
Andrea Boriero May 2, 2024 at 1:43 PM
Edited
Hi ,
I’m working on a solution for this issue but in order to make your test working it requires to changes.
The first one is related to your ModelGenerator service
where
should be changed to
and the second to your ModelExecutor
where
should be changed to
and
to
this second change is necessary because Spring save method behind the scene uses Hibernate merge method and your code using the original childModelFirst was working by change due to a change made to Hibernate that we discovered was violating the JPA spec and for this reason it has been reverted.
Andrea Boriero May 2, 2024 at 10:32 AM
Hi
thanks for the reproducer.
Wieslaw Madycki April 30, 2024 at 9:51 PM
Hi
I've prepared an example project which reproduces reported issue. I've posted the code on github.
I've tried build project as simple as possible. However, if there will be something unclear or wrong from your point of view please let me know I will try to explain more specific.
Thank you,
Andrea Boriero April 30, 2024 at 6:42 AM
Hi ,
can you please provide a reproducer? it would be really helpful
I have some legacy code that I'm working with and uses composite-id for some entities, I have also custom IdGenerator for the one of id.
The generator generates the id correctly, but during flush operation hibernate throws following exception:
Caused by: org.hibernate.HibernateException: identifier of an instance of some.company.modules.model.ModelY was altered from CompositeId: code='WT1' | revision='0' to CompositeId: code='null' | revision='0'
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:98)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:182)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:141)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:234)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:79)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1411)
at org.hibernate.query.sql.internal.NativeQueryImpl.prepareForExecution(NativeQueryImpl.java:601)
at org.hibernate.query.spi.AbstractSelectionQuery.beforeQuery(AbstractSelectionQuery.java:452)
at org.hibernate.query.spi.AbstractSelectionQuery.beforeQueryHandlingFetchProfiles(AbstractSelectionQuery.java:439)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:420)
at org.hibernate.query.Query.getResultList(Query.java:120)
Flush is forced by HQL query checking if new generated code does not exist in database (Query.getResultList). It looks like the problem is in ‘AbstractSaveEventListener::performSave'. This method does not support ‘CompositeNestedGeneratedValueGenerator’. Please see attachment.
Exception occurs since 6.3.x version. 6.2.x and earlier versions works fine.