Issue
I have created the below OneToOne relationship with Hibernate and Kotlin. However, when I am Initializing Parent()
it requires me to set child
value as Parent(child=null)
which is not desired. Only initializing child should require parent as Child(parent=Parent(...)
and if I add both parent to child and child to parent, it creates an infinite loop. What it the right way to avoid that?
@Entity
class Parent(
@Id
@Column(nullable = false, updatable = false, columnDefinition = "uuid")
val id: UUID = UUID.randomUUID(),
@OneToOne(cascade = [CascadeType.ALL], mappedBy = "parent")
@JsonIgnore
@JoinColumn(name = "child_id", referencedColumnName = "id")
val child: Child?
)
@Entity
class Subscriber(
@Id
@Column(nullable = false, updatable = false, columnDefinition = "uuid")
val id: UUID = UUID.randomUUID(),
@OneToOne(cascade = [CascadeType.ALL], optional = false)
@JoinColumn(name = "id", columnDefinition = "uuid")
@MapsId
val parent: Parent
)
Solution
As parent and child are mapped one to one and you want to use @MapsId to not create another extra PK in child table. Now Child object will use parent_id has its own PK.
For Parent
@Entity
public class Parent {
@Id
@Column(nullable = false, updatable = false, columnDefinition = "uuid")
private UUID id = UUID.randomUUID();
public UUID getId() {
return id;
}
public Parent setId(UUID id) {
this.id = id;
return this;
}
}
Child
@Entity
public class Child {
@Id
@Column(nullable = false, updatable = false, columnDefinition = "uuid")
private UUID id = UUID.randomUUID();
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Parent parent;
public UUID getId() {
return id;
}
public Child setId(UUID id) {
this.id = id;
return this;
}
public Parent getParent() {
return parent;
}
public Child setParent(Parent parent) {
this.parent = parent;
return this;
}
}
Check below screenshot for how table will look in database.
Answered By - Sagar Rout
Answer Checked By - David Marino (JavaFixing Volunteer)