Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Persist parent and child with one to many relationship

I want to persist parent entity with 20 child entities, my code is below

Parent Class

@OneToMany(mappedBy = "parentId") private Collection<Child> childCollection; 

Child Class

@JoinColumn(name = "parent_id", referencedColumnName = "parent_id") @ManyToOne(optional=false) private Parent parent; 

String jsonString = "json string containing parent properties and child  collection"   ObjectMapper mapper = new ObjectMapper(); Parent parent = mapper.readValue(jsonString, Parent.class);  public void save(Parent parent) {     Collection<Child> childCollection = new ArrayList<>() ;      for(Child tha : parent.getChildCollection()) {          tha.setParent(parent);         childCollection.add(tha);     }      parent.setChildCollection(childCollection);     getEntityManager().persist(parent);  } 

So if there are 20 child tables then I have to set parent reference in each of them for that I have to write 20 for loops? Is it feasible? is there any other way or configuration where I can automatically persist parent and child?

like image 632
Gora Avatar asked Feb 04 '16 10:02

Gora


People also ask

How do you persist many to many relationships in JPA?

In JPA we use the @ManyToMany annotation to model many-to-many relationships. This type of relationship can be unidirectional or bidirectional: In a unidirectional relationship only one entity in the relationship points the other. In a bidirectional relationship both entities point to each other.

How do you update parent and child records in JPA?

My parent class : @Entity @DynamicUpdate @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType. IDENTITY) @Column(name="person_pk", nullable=false) private Long personPK; @OneToMany(fetch = FetchType. EAGER, mappedBy = "person",cascade = CascadeType.


2 Answers

Fix your Parent class:

@OneToMany(mappedBy = "parent") 

mappedBy property should point to field on other side of relationship. As JavaDoc says:

The field that owns the relationship. Required unless the relationship is unidirectional.

Also you should explicitely persist Child entity in cycle:

for(Child tha : parent.getChildCollection()) {      ...     getEntityManager().persist(tha);     ... } 

As Alan Hay noticed in comment, you can use cascade facilities and let EntityManager automatically persist all your Child entities:

@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) 

More details about cascades (and JPA itself) you can find in Vlad Mihalcea's blog.

like image 147
Ivan Babanin Avatar answered Sep 22 '22 19:09

Ivan Babanin


Generally, @JoinColumn indicates that the entity is the owner of the relationship & mappedBy indicates that the entity is the inverse of the relationship.

So, if you are trying like following

@OneToMany(mappedBy = "parent") private Collection<Child> childCollection; 

That means it is inverse of the relationship and it will not set parent reference to its child.

To set parent reference to its child, you have to make the above entity owner of the relationship in the following way.

@OneToMany(cascade = CascadeType.ALL) @JoinColumn private Collection<Child> childCollection; 

You need not set any child reference because above code will create a column in the child table.

like image 21
maruf571 Avatar answered Sep 20 '22 19:09

maruf571