2

I was trying to save a table using Hibernate. The Parent table has One To many Relationship with its Child table. The parent table POJO has a collection of its Child tables POJO.

When I am saving the Parent table the data gets inserted into its child table as well but without its foreign key as NULL.

Below is my code: Parent:

public class Parent implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 45)
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "parentid", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
private Collection<Child> childCollection;

public Parent() {
}

public Parent(Integer id) {
    this.id = id;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@XmlTransient
public Collection<Child> getChildCollection() {
    return childCollection;
}

public void setChildCollection(Collection<Child> childCollection) {
    this.childCollection = childCollection;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Parent)) {
        return false;
    }
    Parent other = (Parent) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "beans.Parent[ id=" + id + " ]";
}
}

Child:

public class Child implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 45)
@Column(name = "comments")
private String comments;
@JoinColumn(name = "parentid", referencedColumnName = "id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Parent parentid;

public Child() {
}

public Child(Integer id) {
    this.id = id;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getComments() {
    return comments;
}

public void setComments(String comments) {
    this.comments = comments;
}

public Parent getParentid() {
    return parentid;
}

public void setParentid(Parent parentid) {
    this.parentid = parentid;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Child)) {
        return false;
    }
    Child other = (Child) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "beans.Child[ id=" + id + " ]";
} }

Hibernate Service:

public class HibernateSave {
public static void main(String[] args) {
            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    Session session = sessionFactory.openSession();

            Transaction tx1 = session.beginTransaction();

    Parent parent = new Parent();
            Child child1 = new Child();
            parent.setName("Name");
            child1.setComments("Hey");
            //child1.setParentid(parent);
            List<Child> childs = new ArrayList<Child>();
            childs.add(child1);


            parent.setChildCollection(childs);

            System.out.println("parent Saved id="+session.save(parent));
            tx1.commit();
    session.flush(); //address will not get saved without this
    System.out.println("*****");



} }

I found a solution where I reversed mapped my child to parent as below

child1.setParentid(parent);

But I am thinking if this could be avoided. I hope there is anyother way round where I donot need to map my every child to its parent.

Kinldy help and also if you could explain.

2
  • Have you tried adding @ManyToOne(cascade=CascadeType.ALL) to your child entity? Commented Nov 12, 2018 at 13:48
  • yes, but no luck Commented Nov 12, 2018 at 14:05

1 Answer 1

2

If you update one side of a bi-directional relationship you also have to update the other end of it as it's the applications responsibility to maintain the correct state of the Domain Model.

One thing you could do is create a method in Parent to add Childs:

public void addChild(Child child) {
    childCollection.add(child);
    child.setParentId(this);
}

or/and the other way round in Child:

public void setParent(Parent parent) {
    parent.getChildCollection().add(this);
    this.setParentId(parent)
}

(code without necessary null-checks etc. but should give the idea)

and thus making the code a little less error-prone (i.e. forgetting to update the other side of the relationship).

There also seems to be a Bytecode-Enhancement which will add similar code to the class files of your entities, but I have no experience with how well that works (see here for details)

Sign up to request clarification or add additional context in comments.

2 Comments

Hey Tom, thanks for your answer. I understood. The thing is I am sending my complete POJO to the controller through JSON. The POJO has Parent with its Childs. So eventually I have to set the Child or parent again before session.save(parent). Could it be avoided?
Not sure I understand your scenario correctly, since you transfer the POJO through JSON wouldn't you have to merge it after you get it back (before save)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.