pointerless
pointerless

Reputation: 753

JPA/Hibernate OnetoMany preventing duplicate children

There are a few different questions around this topic that have had answers but from what I can see many answers are old or don't make clear sense to me.

Let's say I have an Entity/Table:

@Entity
@Table(name = "ParentTable")
public class Parent {

    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany(cascade = CascadeType.ALL)
    @NotNull
    private List<Child> children;

    public Parent(String childLabel){
        this.children = new ArrayList<>();
        this.children.add(new Child(childLabel));
    }

    // Get/Set/Constructors

}

Then Child as:

@Entity
public class Child {

    @Id
    @GeneratedValue
    private Integer id;

    @NotNull
    private String label;

    public Child(String label){
         this.label = label;
    }

    // Get/Set/Constructors

}

And I then construct some parents by:

String childLabel = "child-label";
Parent a = new Parent(childLabel);
Parent b = new Parent(childLabel);
// Save both parents to a db 

It creates two instances of the child in the table with different IDs. I understand that it is because different instances of the Child are being created and then saved separately.

But how should I go about changing my design to ensure only one instance of two identical children is saved and referenced? I have tried constructing the child then giving to the parents but then I get a primary key error.

Upvotes: 0

Views: 501

Answers (1)

SquatcHman
SquatcHman

Reputation: 67

Alter your constructor to take a Child instead:

public Parent(Child childLabel){
    this.children = new ArrayList<>();
    this.children.add(childLabel);
}

If you want to enforce uniqueness for the label on Child then change the column definition in Child

@Column(unique=true, nullable=false)
private String label;

If more than one Parent needs to reference the same child then you may need to use a ManyToMany type reference instead of One to Many.

Upvotes: 2

Related Questions