Referential Integrity Constraint Violation - Unidirectional OneToOne with Cascade.ALL, optional false and @PrimaryKeyColumnJoin

Description

Beginning from 5.2.14 our use case is not working anymore because of the change in HHH-9460. Our code looks like in the following:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 @Entity @Table(name = "PARENT") ParentContainerEntity { @Id @Column private String correlationId; @OneToMany(orphanRemoval = true, fetch = FetchType.EAGER) @JoinTable(name = "a_parent_to_a", joinColumns = {@JoinColumn(name = "correlation_id")}, inverseJoinColumns = {@JoinColumn(name = "a_entity_id")}) private Set<AEntity> aEntities; @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "a_parent_to_b", joinColumns = {@JoinColumn(name = "correlation_id")}, inverseJoinColumns = {@JoinColumn(name = "b_entity_id")}) private Set<BEntity> bEntities; @OneToOne(cascade = CascadeType.ALL, optional = false, orphanRemoval = true) @PrimaryKeyJoinColumn private CEntity cEntity; } @Entity @Table(name = "C") public class CEntity { @Id @Column private String correlationId; @Lob @Column(nullable = false) @Convert(converter = AddressConverter.class) private List<String> addressLines; @Column(nullable = false) private String letterDate; @Column(nullable = false, length = 500) private String salutation; }

Our use case is to share ID of parent without using Bidirectional association and while persisting parent, the child should be persisted with the ID of parent.

Before version 5.2.14, order of the relevant insert statements was:

1 2 - Hibernate: insert into letter_data (address_lines, letter_date, salutation, correlation_id) values (?, ?, ?, ?) - Hibernate: insert into std_ex_ante (correlation_id) values (?)

Beginning from version 5.2.14, the order is:

1 2 - Hibernate: insert into std_ex_ante (correlation_id) values (?) - Hibernate: insert into letter_data (address_lines, letter_date, salutation, correlation_id) values (?, ?, ?, ?)

This happens because parent has a foreign key constraint onto ID of child. If the parent will be persisted as first, child and ID of it does not exist, which causes ConstraintViolationException on flush.

Here is the Exception:

1 2 3 Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKC2NMCOGEPOMQCDYOHBAEDLC73: PUBLIC.PARENT FOREIGN KEY(CORRELATION_ID) REFERENCES PUBLIC.C(CORRELATION_ID) ('cor_12345')" Referential integrity constraint violation: "FKC2NMCOGEPOMQCDYOHBAEDLC73: PUBLIC.PARENT FOREIGN KEY(CORRELATION_ID) REFERENCES PUBLIC.C(CORRELATION_ID) ('cor_12345')"; SQL statement: insert into parent (correlation_id) values (?) [23506-196]

Problem in code is in class OneToOneSecondPass.java

1 2 3 4 5 6 7 8 9 10 if ( value.isReferenceToPrimaryKey() ) { value.setForeignKeyType( ForeignKeyDirection.TO_PARENT ); } else { value.setForeignKeyType( value.isConstrained() ? ForeignKeyDirection.FROM_PARENT : ForeignKeyDirection.TO_PARENT ); }

Beginning from version 5.2.14 value.setForeignKeyType will be set to ForeignKeyDirection.TO_PARENT in our code. It was and should be set to ForeignKeyDirection.FROM_PARENT before version 5.2.14.

I tested this with the code above on 5.2.13.Final and there is no problem.

Environment

Windows 7 Enterprise
H2-Database 1.4.196
Spring Boot 2.0.0.Release

Status

Assignee

Unassigned

Reporter

Veli Döngelci

Fix versions

None

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Feedback Requested

2019/02/05

Worked in

5.2.13

Feedback Requested By

Gail Badner

Components

Affects versions

5.2.14
5.2.15

Priority

Critical
Configure