I created a project which showcases the issue: https://github.com/schnesim/SpringTest
It comprises two entities linked like this:
<changeSet author="simon" id="table1">
<createTable tableName="table1">
<column name="CRYPTID" type="VARCHAR(255)">
<constraints nullable="false" />
</column>
</createTable>
<addPrimaryKey columnNames="CRYPTID" tableName="table1" />
</changeSet>
<changeSet author="simon" id="table2">
<createTable tableName="table2">
<column name="FK_CRYPTID" type="VARCHAR(255)">
<constraints nullable="false" foreignKeyName="FK_CRYPTID"
references="table1(cryptid)" deleteCascade="true" />
</column>
<column name="PERS_ID" type="VARCHAR(255)" />
</createTable>
<addPrimaryKey columnNames="FK_CRYPTID" tableName="table2" />
When you run the project and call http://localhost:8080/save two entities get stored in their corresponding tables.
When I change the parent in the pom.xml to say <version>2.2.2-RELEASE</version
the save operation failes with an org.hibernate.exception.ConstraintViolationException.
Comment From: wilkinsona
Thanks for the sample. The change in behaviour appears to be due to a change in behaviour in Hibernate 5.4.x. With Spring Boot 2.1.x (Hibernate 5.3.x) and SQL logging enabled (logging.level.sql=debug), the following is output:
2020-01-12 15:48:19.936 DEBUG 83902 --- [nio-8080-exec-1] org.hibernate.SQL : select table1x0_.cryptid as cryptid1_0_1_, table2x1_.fk_cryptid as fk_crypt1_1_0_, table2x1_.pers_id as pers_id2_1_0_ from table1 table1x0_ left outer join table2 table2x1_ on table1x0_.cryptid=table2x1_.fk_cryptid where table1x0_.cryptid=?
2020-01-12 15:48:19.950 DEBUG 83902 --- [nio-8080-exec-1] org.hibernate.SQL : select table2x0_.fk_cryptid as fk_crypt1_1_0_, table2x0_.pers_id as pers_id2_1_0_ from table2 table2x0_ where table2x0_.fk_cryptid=?
2020-01-12 15:48:19.955 DEBUG 83902 --- [nio-8080-exec-1] org.hibernate.SQL : insert into table1 (cryptid) values (?)
2020-01-12 15:48:19.957 DEBUG 83902 --- [nio-8080-exec-1] org.hibernate.SQL : insert into table2 (pers_id, fk_cryptid) values (?, ?)
With Spring Boot 2.2.x (Hibernate 5.4.x) the following is output:
2020-01-12 15:49:48.309 DEBUG 84067 --- [nio-8080-exec-1] org.hibernate.SQL : select table1x0_.cryptid as cryptid1_0_0_ from table1 table1x0_ where table1x0_.cryptid=?
2020-01-12 15:49:48.315 DEBUG 84067 --- [nio-8080-exec-1] org.hibernate.SQL : select table2x0_.fk_cryptid as fk_crypt1_1_0_, table2x0_.pers_id as pers_id2_1_0_ from table2 table2x0_ where table2x0_.fk_cryptid=?
2020-01-12 15:49:48.329 DEBUG 84067 --- [nio-8080-exec-1] org.hibernate.SQL : insert into table2 (pers_id, fk_cryptid) values (?, ?)
2020-01-12 15:49:48.332 WARN 84067 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23506, SQLState: 23506
2020-01-12 15:49:48.332 ERROR 84067 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Referential integrity constraint violation: "FK_CRYPTID: PUBLIC.TABLE2 FOREIGN KEY(FK_CRYPTID) REFERENCES PUBLIC.TABLE1(CRYPTID) ('ee855cd9-493a-440a-950a-17b7c130fc19')"; SQL statement:
insert into table2 (pers_id, fk_cryptid) values (?, ?) [23506-200]
Note that the insert into table2
is now being attempted first.
Unfortunately, this ordering is out of Spring Boot's control as it is determined by Hibernate. It may be that what you are doing is no longer supported by Hibernate (although I cannot see why that would be the case) or this may be a bug. If it is a bug, it should be raised with the Hibernate team.
If you do raise this with the Hibernate team, please comment here with a link so that we can follow along.