0

I would like to understand this basic concept. How do we save the child entity and populate the foreign Key ID in the Child table. I have this situation where Parent Can have many child. But the Child can only have one Parent.

`

Entity
@Table(name = "Child")
@SuppressWarnings("serial")
public class Child implements java.io.Serializable {

@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;


}

-------------------------

@Entity
@Table(name = "parent")
@SuppressWarnings("serial")
public class Parent {


@OneToMany(mappedBy = "parent", fetch=FetchType.LAZY, cascade = CascadeType.ALL)
private List<Child> children;

}



` I am trying to save the child like this below. but its giving me exception that

column "parent" of relation "child" does not exist

Child child = new Child();
child.setParent(parent);
child.setXYZ("XYZ");

childRepository.save(child);

I am trying to save the child entity and expecting it to save the parent_id column automatically. I also tried creating another field in the child entity called

private Long parentId;

and tried to replace this line

child.setParent(parent)

with child.setParentId(parentId);

but nothing is working

Turo
  • 4,724
  • 2
  • 14
  • 27
  • Case is important! I assume `private Parent Parent` is a typo – Turo Aug 18 '23 at 19:27
  • Thanks a lot for pointing it out. This was a typo only in my question. In my code, its right case. – Rajesh Java guy Aug 18 '23 at 19:51
  • The error doesn't quite make sense - maybe post the exact exception and stack. Ignoring its inconsistencies, I would take it to mean that your JPA provider is processing the mappedBy on the OneToMany, and cannot find the 'parent' reference in the Child entity. Why is not clear (it says "child" not "Child). I'd try removing that mapping (the OneToMany) outright and see if your Child entity is actually getting processed and can be persisted or if there are other errors masked somehow. A Bidirectional 1:M mapping is so very common, so the problem will be hidden in what you haven't shown – Chris Aug 23 '23 at 15:13

1 Answers1

1

What you are trying to implement in bidirectional One To Many relationship. And, in bidirectional relationship you should set the both side of the reference.

  1. Initialize the child list in parent entity as: private List<Child> children = new ArrayList<>();

  2. Add an utility method in parent which ensures both side of the references are saved.

    public void addChildren(Children child) {
        children.add(child);
        child.setParent(this);
    }
    
  3. Create parent object, refer child and save.

    Parent parent = new Parent();
    parent.addChildren(new Child());
    parentRepository.save(parent);
    

A good read: https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/

If the parent already exists (and lets say has id = 1), and you need to add another child, you can do something like:

Parent parent = parentRepository.findById(id);
parent.addChildren(new Child());
parentRepository.save(parent);
hermit
  • 1,048
  • 1
  • 6
  • 16
  • 1
    I'd advise against the last bit. If Parent already exists, you should find the instance from the context and add a child to it instead of creating a new one. if you create a new one and then call save on it, you are merging that empty Parent instance into the context - it will overwrite all other Parent data in the entity/db with the empty Parent data. Maybe you meant to call save on the Child instead - this works as long as the Child->parent relationship doesn't have cascade merge/persist set. – Chris Aug 23 '23 at 15:06
  • @Chris, thank you for pointing out. Have updated the code. – hermit Aug 24 '23 at 13:43