On Hibernate ORM 7.2.19.Final, calling merge() on an already-managed parent whose orphanRemoval = true collection has been emptied throws org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context during flush. The same code runs without error on 6.6.53.Final (the orphan is deleted normally). Using persist() instead of merge() in the exact same scenario also works.
This looks like a regression. Minimal, self-contained reproduction below (pure Hibernate, no Spring).
Entities
@Entity
public class DetachParent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<DetachChild> children = new ArrayList<>();
public Long getId() {
return id;
}
public List<DetachChild> getChildren() {
return children;
}
}
@Entity
public class DetachChild {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private DetachParent parent;
public Long getId() { return id; }
public DetachParent getParent() { return parent; }
public void setParent(DetachParent invoice) { this.parent = invoice; }
}
public void setParent(DetachParent parent) { this.parent = parent; }
}
Test
public class DetachTest {
/**
* Creates a parent with a child in a transaction
* When the transaction closes, the session is not discarded due to open-session-in-view
* Clear the child in a different transaction
*/
@Test
void mergeOfManagedParentWithClearedOrphanCollection() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
try (emf) {
EntityManager entityManager = emf.createEntityManager();
DetachParent parent = createParentWithChildInTx(entityManager);
parent.getChildren().clear();
entityManager.getTransaction().begin();
System.out.println("[tx2] em.contains(parent) BEFORE merge = " + entityManager.contains(parent));
// Spring JPA saveAndFlush does merge+flush
entityManager.merge(parent);
entityManager.flush();
entityManager.getTransaction().commit();
entityManager.close();
}
}
/**
* Creates a parent with a child in a transaction
* When the transaction closes, the session is not discarded due to open-session-in-view
* Clear the child and a new child in a different transaction
*/
@Test
void mergeOfManagedParentWithClearedOrphanCollectionAndNewEntry() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
try (emf) {
EntityManager entityManager = emf.createEntityManager();
DetachParent parent = createParentWithChildInTx(entityManager);
parent.getChildren().clear();
// Adding a new child does not cause the DetachException
DetachChild child = new DetachChild();
child.setParent(parent);
parent.getChildren().add(child);
entityManager.getTransaction().begin();
System.out.println("[tx2] em.contains(parent) BEFORE merge = " + entityManager.contains(parent));
// Spring JPA saveAndFlush does merge+flush
entityManager.merge(parent);
entityManager.flush();
entityManager.getTransaction().commit();
entityManager.close();
}
}
DetachParent createParentWithChildInTx(EntityManager entityManager) {
entityManager.getTransaction().begin();
DetachParent parent = new DetachParent();
DetachChild child = new DetachChild();
child.setParent(parent);
parent.getChildren().add(child);
entityManager.persist(parent);
entityManager.flush();
entityManager.getTransaction().commit();
return parent;
}
}
Expected vs actual
- Expected: orphan removal deletes the child — as it does under
persist()in the same scenario, and asmerge()does on 6.5.2. - Actual (7.2.19): the orphan child is routed through the detached-delete path and throws:
Caused by: org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context
at org.hibernate.event.internal.DefaultDeleteEventListener.deleteDetachedEntity(DefaultDeleteEventListener.java:170)
at org.hibernate.event.internal.DefaultDeleteEventListener.deleteUnmanagedInstance(DefaultDeleteEventListener.java:163)
at org.hibernate.event.internal.DefaultDeleteEventListener.delete(DefaultDeleteEventListener.java:148)
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:84)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:149)
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:911)
A multimodule that contains both hibernate 6 and 7. Run mvn clean test to reproduce the problem:
/IdeaProjects/robaws/hibernateOrphanRemoval$ mvn clean test
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::load has been called by org.fusesource.jansi.internal.JansiLoader in an unnamed module (file:/home/devlooj/.sdkman/candidates/maven/current/lib/jansi-2.4.0.jar)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper (file:/home/devlooj/.sdkman/candidates/maven/current/lib/guava-32.0.1-jre.jar)
WARNING: Please consider reporting this to the maintainers of class com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] hibernateOrphanRemoval [pom]
[INFO] hibernate6 [jar]
[INFO] hibernate7 [jar]
[INFO]
[INFO] ------------------< be.eforge:hibernateOrphanRemoval >------------------
[INFO] Building hibernateOrphanRemoval 1.0-SNAPSHOT [1/3]
[INFO] from pom.xml
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ hibernateOrphanRemoval ---
[INFO]
[INFO] ------------------------< be.eforge:hibernate6 >------------------------
[INFO] Building hibernate6 1.0-SNAPSHOT [2/3]
[INFO] from hibernate6/pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ hibernate6 ---
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ hibernate6 ---
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ hibernate6 ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 2 source files with javac [debug target 25] to target/classes
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ hibernate6 ---
[INFO] skip non existing resourceDirectory /home/devlooj/IdeaProjects/robaws/hibernateOrphanRemoval/hibernate6/src/test/resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ hibernate6 ---
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 1 source file with javac [debug target 25] to target/test-classes
[INFO]
[INFO] --- surefire:3.2.2:test (default-test) @ hibernate6 ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DetachTest
Jul 03, 2026 8:35:09 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: pu]
Jul 03, 2026 8:35:09 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 6.6.53.Final
Jul 03, 2026 8:35:09 AM org.hibernate.cache.internal.RegionFactoryInitiator initiateService
INFO: HHH000026: Second-level cache disabled
Jul 03, 2026 8:35:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
Jul 03, 2026 8:35:09 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator logConnectionInfo
INFO: HHH10001005: Database info:
Database JDBC URL [jdbc:h2:mem:t;DB_CLOSE_DELAY=-1]
Database driver: org.h2.Driver
Database version: 2.3.232
Autocommit mode: false
Isolation level: undefined/unknown
Minimum pool size: 1
Maximum pool size: 20
Hibernate: create global temporary table HTE_DetachParent(rn_ integer not null, id bigint, primary key (rn_)) TRANSACTIONAL
Hibernate: create global temporary table HTE_DetachChild(rn_ integer not null, id bigint, parent_id bigint, primary key (rn_)) TRANSACTIONAL
Jul 03, 2026 8:35:10 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate: drop table if exists DetachChild cascade
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@147cc940] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists DetachParent cascade
Hibernate: drop sequence if exists DetachChild_SEQ
Hibernate: drop sequence if exists DetachParent_SEQ
Hibernate: create sequence DetachChild_SEQ start with 1 increment by 50
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@6562cc23] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create sequence DetachParent_SEQ start with 1 increment by 50
Hibernate: create table DetachChild (id bigint not null, parent_id bigint, primary key (id))
Hibernate: create table DetachParent (id bigint not null, primary key (id))
Hibernate: alter table if exists DetachChild add constraint FK2bi4x2h6r50llqyorusw6g2rh foreign key (parent_id) references DetachParent
Hibernate: select next value for DetachParent_SEQ
Hibernate: select next value for DetachChild_SEQ
Hibernate: insert into DetachParent (id) values (?)
Hibernate: insert into DetachChild (parent_id,id) values (?,?)
[tx2] em.contains(parent) BEFORE merge = true
Hibernate: delete from DetachChild where id=?
Hibernate: drop table if exists DetachChild cascade
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@7bede4ea] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists DetachParent cascade
Hibernate: drop sequence if exists DetachChild_SEQ
Hibernate: drop sequence if exists DetachParent_SEQ
Jul 03, 2026 8:35:10 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: pu]
Jul 03, 2026 8:35:10 AM org.hibernate.cache.internal.RegionFactoryInitiator initiateService
INFO: HHH000026: Second-level cache disabled
Jul 03, 2026 8:35:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
Jul 03, 2026 8:35:10 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator logConnectionInfo
INFO: HHH10001005: Database info:
Database JDBC URL [jdbc:h2:mem:t;DB_CLOSE_DELAY=-1]
Database driver: org.h2.Driver
Database version: 2.3.232
Autocommit mode: false
Isolation level: undefined/unknown
Minimum pool size: 1
Maximum pool size: 20
Hibernate: create global temporary table HTE_DetachParent(rn_ integer not null, id bigint, primary key (rn_)) TRANSACTIONAL
Hibernate: create global temporary table HTE_DetachChild(rn_ integer not null, id bigint, parent_id bigint, primary key (rn_)) TRANSACTIONAL
Jul 03, 2026 8:35:10 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate: drop table if exists DetachChild cascade
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@7e2c6702] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists DetachParent cascade
Hibernate: drop sequence if exists DetachChild_SEQ
Hibernate: drop sequence if exists DetachParent_SEQ
Hibernate: create sequence DetachChild_SEQ start with 1 increment by 50
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@5fb7ab9c] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create sequence DetachParent_SEQ start with 1 increment by 50
Hibernate: create table DetachChild (id bigint not null, parent_id bigint, primary key (id))
Hibernate: create table DetachParent (id bigint not null, primary key (id))
Hibernate: alter table if exists DetachChild add constraint FK2bi4x2h6r50llqyorusw6g2rh foreign key (parent_id) references DetachParent
Hibernate: select next value for DetachParent_SEQ
Hibernate: select next value for DetachChild_SEQ
Hibernate: insert into DetachParent (id) values (?)
Hibernate: insert into DetachChild (parent_id,id) values (?,?)
[tx2] em.contains(parent) BEFORE merge = true
Hibernate: select next value for DetachChild_SEQ
Hibernate: insert into DetachChild (parent_id,id) values (?,?)
Hibernate: delete from DetachChild where id=?
Hibernate: drop table if exists DetachChild cascade
Jul 03, 2026 8:35:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@4d43a1b7] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists DetachParent cascade
Hibernate: drop sequence if exists DetachChild_SEQ
Hibernate: drop sequence if exists DetachParent_SEQ
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.093 s -- in DetachTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] ------------------------< be.eforge:hibernate7 >------------------------
[INFO] Building hibernate7 1.0-SNAPSHOT [3/3]
[INFO] from hibernate7/pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ hibernate7 ---
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ hibernate7 ---
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ hibernate7 ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 3 source files with javac [debug target 25] to target/classes
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ hibernate7 ---
[INFO] skip non existing resourceDirectory /home/devlooj/IdeaProjects/robaws/hibernateOrphanRemoval/hibernate7/src/test/resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ hibernate7 ---
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 1 source file with javac [debug target 25] to target/test-classes
[INFO]
[INFO] --- surefire:3.2.2:test (default-test) @ hibernate7 ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DetachTest
Jul 03, 2026 8:35:10 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH008540: Processing PersistenceUnitInfo [name: pu]
Jul 03, 2026 8:35:10 AM org.hibernate.Version logVersion
INFO: HHH000001: Hibernate ORM core version 7.2.19.Final
Jul 03, 2026 8:35:11 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProvider configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
Jul 03, 2026 8:35:11 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator logConnectionInfo
INFO: HHH10001005: Database info:
Database JDBC URL [jdbc:h2:mem:t;DB_CLOSE_DELAY=-1]
Database driver: H2 JDBC Driver
Database dialect: H2Dialect
Database version: 2.3.232
Default catalog/schema: T/PUBLIC
Autocommit mode: false
Isolation level: READ_COMMITTED
JDBC fetch size: 100
Pool: DriverManagerConnectionProvider
Minimum pool size: 1
Maximum pool size: 20
Jul 03, 2026 8:35:11 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate: drop table if exists DetachChild cascade
Hibernate: drop table if exists DetachParent cascade
Hibernate: create table DetachChild (id bigint generated by default as identity, parent_id bigint, primary key (id))
Hibernate: create table DetachParent (id bigint generated by default as identity, primary key (id))
Hibernate: alter table if exists DetachChild add constraint FK2bi4x2h6r50llqyorusw6g2rh foreign key (parent_id) references DetachParent
Hibernate: insert into DetachParent (id) values (default)
Hibernate: insert into DetachChild (parent_id,id) values (?,default)
[tx2] em.contains(parent) BEFORE merge = true
Hibernate: delete from DetachChild where id=?
Hibernate: drop table if exists DetachChild cascade
Hibernate: drop table if exists DetachParent cascade
Jul 03, 2026 8:35:11 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH008540: Processing PersistenceUnitInfo [name: pu]
Jul 03, 2026 8:35:11 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProvider configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
Jul 03, 2026 8:35:11 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator logConnectionInfo
INFO: HHH10001005: Database info:
Database JDBC URL [jdbc:h2:mem:t;DB_CLOSE_DELAY=-1]
Database driver: H2 JDBC Driver
Database dialect: H2Dialect
Database version: 2.3.232
Default catalog/schema: T/PUBLIC
Autocommit mode: false
Isolation level: READ_COMMITTED
JDBC fetch size: 100
Pool: DriverManagerConnectionProvider
Minimum pool size: 1
Maximum pool size: 20
Jul 03, 2026 8:35:11 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate: drop table if exists DetachChild cascade
Hibernate: drop table if exists DetachParent cascade
Hibernate: create table DetachChild (id bigint generated by default as identity, parent_id bigint, primary key (id))
Hibernate: create table DetachParent (id bigint generated by default as identity, primary key (id))
Hibernate: alter table if exists DetachChild add constraint FK2bi4x2h6r50llqyorusw6g2rh foreign key (parent_id) references DetachParent
Hibernate: insert into DetachParent (id) values (default)
Hibernate: insert into DetachChild (parent_id,id) values (?,default)
[tx2] em.contains(parent) BEFORE merge = true
Hibernate: insert into DetachChild (parent_id,id) values (?,default)
Hibernate: delete from DetachChild where id=?
Hibernate: drop table if exists DetachChild cascade
Hibernate: drop table if exists DetachParent cascade
[ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.156 s <<< FAILURE! -- in DetachTest
[ERROR] DetachTest.mergeOfManagedParentWithClearedOrphanCollection -- Time elapsed: 1.096 s <<< ERROR!
jakarta.persistence.RollbackException: Error while committing the transaction [org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:73)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:92)
at DetachTest.mergeOfManagedParentWithClearedOrphanCollection(DetachTest.java:26)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
Caused by: java.lang.IllegalArgumentException: org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:153)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:168)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:174)
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:922)
at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:851)
at org.hibernate.engine.internal.Cascade.deleteOrphans(Cascade.java:637)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:622)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:489)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:452)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:217)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:158)
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:173)
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:129)
at org.hibernate.event.internal.AbstractFlushingEventListener.preFlush(AbstractFlushingEventListener.java:83)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:62)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:138)
at org.hibernate.internal.SessionImpl.fireFlush(SessionImpl.java:1484)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:481)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2111)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2033)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:410)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:166)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:248)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:242)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:89)
... 4 more
Caused by: org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context
at org.hibernate.event.internal.DefaultDeleteEventListener.deleteDetachedEntity(DefaultDeleteEventListener.java:170)
at org.hibernate.event.internal.DefaultDeleteEventListener.deleteUnmanagedInstance(DefaultDeleteEventListener.java:163)
at org.hibernate.event.internal.DefaultDeleteEventListener.delete(DefaultDeleteEventListener.java:148)
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:84)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:149)
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:911)
... 26 more
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] DetachTest.mergeOfManagedParentWithClearedOrphanCollection:26 » Rollback Error while committing the transaction [org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context]
[INFO]
[ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for hibernateOrphanRemoval 1.0-SNAPSHOT:
[INFO]
[INFO] hibernateOrphanRemoval ............................. SUCCESS [ 0.079 s]
[INFO] hibernate6 ......................................... SUCCESS [ 2.214 s]
[INFO] hibernate7 ......................................... FAILURE [ 1.635 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.984 s
[INFO] Finished at: 2026-07-03T08:35:11+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.2.2:test (default-test) on project hibernate7:
[ERROR]
[ERROR] Please refer to /home/devlooj/IdeaProjects/robaws/hibernateOrphanRemoval/hibernate7/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :hibernate7
Observations while narrowing this down
These are things I saw while debugging; I have not pinned the exact merge step responsible, so I’m reporting them as observations rather than a root-cause claim.
- The divergence is visible at
DefaultDeleteEventListener.delete(), at thegetEntry(entity) == nullfork:- 6.5.2: takes
deletePersistentInstance(orphan is still managed). - 7.2.19: takes
deleteUnmanagedInstance→deleteDetachedEntity→ throws under JPA bootstrap.
- 6.5.2: takes
- Diffing 6.5.2 vs 7.2.19, the following are effectively identical (so the change seems to be elsewhere): the
delete()fork itself,CollectionType.preserveSnapshot/createListSnapshot, andEntityType.replace→resolve→resolveIdentifier. - Runtime probe: right before the
merge,em.contains(child) == true; by the time orphan removal runs, there is no managed entity for the child’s key in the persistence context. So the previously-managed child appears to be de-registered from the context duringmerge.persist()does not cause this.
That points upstream of the delete listener. It has to be somewhere in the merge handling for an already-managed parent with an emptied orphanRemoval collection. I couldn’t identify the precise step that removes the child’s EntityEntry.
Is this an intended behavior change or a regression? Is it part of 7.0 Migration Guide ? If it’s a bug I’m happy to open an HHH issue with this reproduction, and can attempt a PR. I searched the forum and JIRA and didn’t find an existing report, but pointers to a duplicate are welcome.