I’ve run into an issue where cascade removals (the Hibernate ones) do propagate into database, but the objects still remain in the Persistence Context, which causes an error.
Here I have prepared a sample project, which reproduces the issue: https://github.com/scadgek/SchemaRegistry. It contains a JUnit test with one method demostrating the problem, on each run the database is recreated based on persistence.xml.
To describe the use case in a few words, imagine you’re trying to store the metadata of an object database (or class hierarchy) into relational database. This way, you have UserDataTableEntity, which has many UserDataTableColumnEntities (for simple fields), some of which can be UserDataTableRelationEntities (for object fields), which relate to some UserDataTableEntity.
What I’m doing in the project is I save some test data first - two tables, one column belonging to the first table, this column is also a relation to the second table. Then I try to remove the tables one by one and expect that everything is cleared up based on entities’ annotations and database constraints. As a result, the first table is removed correctly - I can see there’s nothing left for it in the database, but apparently the Persistence Context is not cleaned up - I can see the Column and Relation entity are still there, and therefore the deletion of the second table fails with the following exception:
javax.persistence.RollbackException: Error while committing the transaction ... Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : edu.scadge.schemaregistry.datamodel.UserDataTableColumnEntity.userDataTable -> edu.scadge.schemaregistry.datamodel.UserDataTableEntity ... Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : edu.scadge.schemaregistry.datamodel.UserDataTableColumnEntity.userDataTable -> edu.scadge.schemaregistry.datamodel.UserDataTableEntity ...
(you can see it in full if you run the test case)
Hope my explanations were at least a bit clear, though anyway you can pull the project above and see everything by yourself - I tried to minimize it as much as possible.
I guess as a solution I need to cleanup the context manually, but I always thought it’s JPA/Hibernate’s responsibility to keep it in sync. Probably I’m missing something, so will be really grateful for any advice.