h2. Minimal project for reproduction
* [https://github.com/lwitzani/hibernate6_singleTableIssue|https://github.com/lwitzani/hibernate6_singleTableIssue|smart-link] * project has two branches (one with hibernate 5 and one with hibernate 6) * the only difference in the branches is the updated versions of spring boot and therefore hibernate * i debugged very deep and think that it is a problem with hibernate at the location where the select statement is generated ({{LoaderSelectBuilder}}.{{createSelect}})
h2. Requisites
* entity ("Person") exists that has a field which is a set of other entities ("Set\<Leg>") * these other entities are derived from an abstract super class ("Leg extends BodyPart") * the abstract super class' inheritance strategy is SINGLE_TABLE
!uml.png|width=517,height=425!
h2. Reproduction
* execute the test PersonPersistenceTest.shouldUseSQLUpdateToChangeThePersonName * the test basically ** creates a Person (without Legs) and saves it using the repository ** refetches the Person by findById ** changes the Person's name ** saves the changed Person again
h2. Observations in Hibernate 5.6.14.Final
* when the second save is called (after changing the name) there will be a select statement which is used to check if the entity already exists ** the body_part table is joined via left outer join ** the where clause here only consists of "where [person.id|http://person.id] = \ <id>" * the entity is correctly found by the select statement so afterwards an update statement follows * result: one entity exists (the changed one)
!hibernate5.png|width=1265,height=692!
h2. Observations in Hibernate 6.1.6.Final
* when the second save is called (after changing the name) there will be a different select statement now ** the body_part table is joined via left join now (not outer) ** the critical change here is that the where clause now suddenly consists of "where body_part.discriminator = 'LegBodyPart' and [person.id|http://person.id] = \ <id>" * although the entity exists, it is not found by the select statement so afterwards an insert statement follows which creates a second Person with a new id * result: two entities exist (the original one and the changed one)
!hibernate6.png|width=1179,height=644!
h1. Summary
* after updating spring boot to 3.0.1 which also updates hibernate to 6.1.6.Final it does not seem to be possible to update an entity with this constellation * the main difference is that an additional and unexpected where clause is added which prevents finding the correct entity in this case * the result is that a new entity is persisted instead of the existing one being updated |
|