Trying to setup a unidirectional foreign key constraint. Child is the relationship owner.
When using 5.3.20-Final, the sql generated when saving would be :
Hibernate: select person0_.id as id1_2_0_, person0_.name as name2_2_0_ from person person0_ where person0_.id=?
Hibernate: select personmeta0_.id as id1_3_0_, personmeta0_.note as note2_3_0_ from
person_metadata personmeta0_ where personmeta0_.id=?
Hibernate: insert into person (name, id) values (?, ?)
Hibernate: insert into person_metadata (note, id) values (?, ?)
After updating to 5.3.21-Final, the sql generated is now:
Hibernate: select person0_.id as id1_2_0_, person0_.name as name2_2_0_ from person person0_ where person0_.id=?
Hibernate: select personmeta0_.id as id1_3_0_, personmeta0_.note as note2_3_0_ from
person_metadata personmeta0_ where personmeta0_.id=?
Hibernate: insert into person_metadata (note, id) values (?, ?)
Hibernate: insert into person (name, id) values (?, ?)
This is triggering the foreign key constraint since there is no associated person that exists yet when the person_metadata record is inserted. Anyone understand what’s causing this?
Example entities below:
Person:
@Entity
@Table(name = "person")
public class Person {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "name")
private String name;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "id")
@Fetch(FetchMode.JOIN)
private PersonMetadata metadata;
public UUID getId(){
return id;
}
public void setId(UUID id){
this.id = id;
}
public String getName(){
return name;
}
public PersonMetadata getMetadata(){
return metadata;
}
public void setName(String name){
this.name = name;
}
public void setMetadata(PersonMetadata metadata){
this.metadata = metadata;
}
Person_Metadata:
@Entity
@Table(name = "person_metadata")
public class PersonMetadata {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "note")
private String note;
@OneToOne()
@PrimaryKeyJoinColumn
//@JoinColumn(name="person_id", referencedColumnName = "id")
private Person person;
public UUID getId(){
return id;
}
public void setId(UUID id){
this.id = id;
}
public String getNote(){
return note;
}
public void setNote(String note){
this.note = note;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person){
this.person = person;
}
}
test case:
@Test
void savePersonAndMetadata() {
UUID id = UUID.randomUUID();
Person testPerson = new Person();
testPerson.setId(id);
testPerson.setName("Foo");
PersonMetadata personMetadata = new PersonMetadata();
personMetadata.setId(id);
personMetadata.setNote("Bar");
testPerson.setMetadata(personMetadata);
personRepository.save(testPerson);
}
The foreign key constraint is defined in a liquibase changelog in the person_metadata table:
<addForeignKeyConstraint baseColumnNames="id"
baseTableName="person_metadata"
constraintName="fk_person_metadata_id_person_id"
onDelete="CASCADE"
referencedColumnNames="id"
referencedTableName="person"/>