Code for really basic example to explain the problem, let’s say I have two tables with the next relation:
create table parent_table(
uuid char(36) primary key,
name varchar(50)
);
create table child_table(
parent_table_uuid char(36) primary key,
name varchar(50),
FOREIGN KEY (parent_table_uuid) REFERENCES parent_table(uuid)
);
Then I have the next JPA Entity classes:
public class Parent {
@Id
@Column(name = "uuid", length = 36)
@Type(type = "uuid-char")
private UUID uuid;
@Column(name = "name")
private String name;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private Child child;
}
public class Child {
@Id
@Column(name = "parent_table_uuid", length = 36)
@Type(type = "uuid-char")
private UUID uuid;
@Column(name = "name")
private String name;
}
And what I try to do is:
@Test
void createAndPersistParentWithChild() {
UUID parentUuid = UUID.randomUUID();
Parent parent = Parent.builder().uuid(parentUuid).name("parent").build();
parent.setChild(Child.builder().uuid(parentUuid).name("child").build());
Parent saved = parentRepository.save(parent);
assertThat(saved.getChild()).isNotNull();
}
My expectation is that both objects will be persisted at once, and a parent object will be persisted first. But what I get is an exception and in the logs I can see that Hibernate generates insert query for the child table first:
Hibernate:
insert
into
child_table
(name, parent_table_uuid)
values
(?, ?)
2024-04-26 15:45:42.509 WARN 46976 --- [Pool-1-worker-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1452, SQLState: 23000
2024-04-26 15:45:42.510 ERROR 46976 --- [Pool-1-worker-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot add or update a child row: a foreign key constraint fails (`test`.`child_table`, CONSTRAINT `fk_child_table_parent_table_uuid_to_parent_table_uuid` FOREIGN KEY (`parent_table_uuid`) REFERENCES `parent_table` (`uuid`))
Do I need to modify something to get it working? If I remove the constraint the code works perfectly fine, and both objects can be saved and retrieved.
Note: I don’t need the reference to the whole Parent
object in the Child object.