I got the following question from a friend the other day.

I have a parent and a child object with a one-to-many relationship by the child’s table having a column that points to it’s parent. What are the correct settings for the mapping in this situation where I need to be able to remove children from the parent’s set, and save the updated parent. It seems like I’ve been through all sorts of combinations, and I was wondering if you could lend me your advice.

The same day I also had a similar question from a colleague at work. I figured I’d post my response here so I could easily find it in the future. I’ve tried to make the code reasonably generic, but watch out for dumb typos.

You should setup the parent mapping like this:

<set name="children" lazy="true" inverse="true">
  <key column="PARENT_ID"/>
  <one-to-many class="my.child.ChildClass"/>
</set>

And then map the child like this:

<many-to-one name="parent" column="PARENT_ID" not-null="false" class="my.parent.ParentClass"/>

Notice that the column name in each refers to THE SAME COLUMN. You’re just connecting the link.

From the parent class:

/** The set of children of this object. */
private Set<ChildClass> children = new HashSet<ChildClass>();
private void setChildren(Set<ChildClass> children) {
    this.children = children;
}

public void removeChild(ChildClass child) {
    children.remove(child);
    child.setParent(null);
}

public void addChild(ChildClass child) throws IllegalArgumentException {
    if (child == null) {
        throw new IllegalArgumentException("Child may not be null");
    }
    if (child.getParent() != null) {
        child.getParent().removeChild(child);
    }
    child.setParent(this);
    children.add(child);
}

From the child class:

/** The parent. */
private ParentClass parent;

This simple example seems to illustrate the basics. My friend later pointed out that one of the things tripping him up was the cascade option. Recognizing that it’s completely separate from the inverse property was a big step. That’s an important point – the inverse just means that the child objects have a property that refers back to the parent. It helps resolve object relationships on load, but the cascade and lazy attributes tell Hibernate when to save and load the objects to and from the database.