Reputation: 1
I'm new to JPA and I can't find a way to correctly initialize a set of child entities when saving the parent using its own repository.
I have this Parent entity which contains a list of child that I want to instantiate when creating the parent such as :
@Entity(name = "parent")
@Table(schema = "XXX", name = "PARENT")
public class Parent {
@Id
@GeneratedValue
@Column(name = "ID_PARENT", nullable = false)
private int idParent;
@OneToMany(targetEntity = Child.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "ID_PARENT", referencedColumnName = "ID_PARENT")
private List<Child> childList= new ArrayList<>();
// Constructor + getters/setters...
The child class (the key of the table is composed of a parent id + its own id, don't ask why) :
@Entity(name = "child")
@Table(schema = "XXX", name = "CHILD")
@IdClass(ChildPrimaryKey.class)
public class Child{
@Id
@Column(name = "ID_CHILD", nullable = false)
private int idChild;
@Id
@Column(name = "ID_PARENT", nullable = false)
private int idParent;
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Parent.class)
@JoinColumn(name = "ID_PARENT", nullable = false, insertable = false, updatable = false)
private Parent parent;
// Constructor + getters/setters...
And finally the ChildPrimaryKey class :
public class ChildPrimaryKey implements Serializable {
private static final long serialVersionUID = XXXL;
private int idChild;
private int idParent;
// Constructors + getters/setters
The problem I'm facing is that there isn't a direct link between the parentId field of the Child class and its parent field. So when I save a Parent entity (with a list of Child initialized inside the childList field) using its repository (basic CrudRepository with some custom queries), then the Parent is correctly saved with its ID getting a generated value, as wanted. But then the Child entities are saved but without the correct ID generated for the parent (by default 0 since it's an int I guess ?), resulting in a constraint violation exception since the column ID_PARENT should refer to an actual Parent id.
I've tried using @PrimaryKeyJoinColumn like this :
@Entity(name = "child")
@Table(schema = "XXX", name = "CHILD")
@IdClass(ChildPrimaryKey.class)
public class Child{
@Id
@Column(name = "ID_CHILD", nullable = false)
private int idChild;
@Id
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Parent.class)
@PrimaryKeyJoinColumn(name = "ID_PARENT", referencedColumnName = "ID_PARENT")
private Parent parent;
// Constructor + getters/setters...
In this case, since the field idParent doesn't exist in the Child class, I get a compilation error because the ChildPrimaryKey class expects the field to be present, plus I need it for my repository queries. (I've also tried adding a int field as before but it still doesn't get any value)
Can anyone explain me what am I doing wrong ? How can I correctly transfer the generated id of the parent when the children are created ?
I would like to avoid having to create the parent first, then getting it's ID to then create the children individually giving them the correct one.
Upvotes: 0
Views: 285
Reputation: 16420
Use this model:
@Entity(name = "parent")
@Table(schema = "XXX", name = "PARENT")
public class Parent {
@Id
@GeneratedValue
@Column(name = "ID_PARENT", nullable = false)
private int idParent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
}
@Entity(name = "child")
@Table(schema = "XXX", name = "CHILD")
@IdClass(ChildPrimaryKey.class)
public class Child {
@Id
@Column(name = "ID_CHILD", nullable = false)
private int idChild;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_PARENT")
private Parent parent;
}
public class ChildPrimaryKey implements Serializable {
private static final long serialVersionUID = XXXL;
private int idChild;
private int parent;
}
Upvotes: 0