Problem with Hibernate many-to-many association

09Nov06

This post is really a record for both myself and anyone else who ever comes across the same problem.

The Problem: Given two entities with a many-to-many association between them, the join table isn’t being populated when an association is made.

The Problem Set: Two persistent entities, “Group” and “ActivityType” with a many-to-many association between them. A few snippets from the relevant files…

Group.hbm.xml

<set name="activityTypes" table="group_activity_type" cascade="save-update" lazy="true">
    <key column="group_id"/>
    <many-to-many column="activity_type_id" class="ActivityType"/>
</set>

ActivityType.hbm.xml

<set name="groups" table="group_activity_type" inverse="true" cascade="save-update" lazy="true">
    <key column="activity_type_id"/>
    <many-to-many column="group_id" class="Group"/>
</set>

Group.java

private Set activityTypes = new HashSet();

public Set getActivityTypes() {
	return activityTypes;
}

public void setActivityTypes(Set activityTypes) {
	this.activityTypes = activityTypes;
}

ActivityType.java

private Set groups = new HashSet();

public Set getGroups() {
	return groups;
}

public void setGroups(Set groups) {
	this.groups = groups;
}

Some test code

org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
session.beginTransaction();

Group group = new Group();
group.setName("Test Group");
ActivityType activityType = new ActivityType();
activityType.setName("Activity Type");
activityType.getGroups().add(group);
group.getActivityTypes().add(activityType);
activityTypeDAO.saveActivityType(activityType);
groupDAO.saveGroup(group);

ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.getTransaction().commit();
session.close();

The Solution: This took me ages to figure out but I eventually stumbled across the problem on this thread. The problem is that I’m not calling session.flush() before I commit the session. Here’s the last paragraph of test code with the new flush statement.

ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.flush();
session.getTransaction().commit();
session.close();
  • Canda
    Many many thanks for this... I was stuck on this for ages too!

    Great job
  • Sat Freak
    Hi there,

    same here, while in a different context:

    Using JPA with Hibernate populating an many-to-many Realtionship, where all Entities on both ends are already persistent. The JoinTable was empty, although no exception was thrown.

    Calling flush() befor calling a merge() did the job!

    Many thanks for this blog!
  • egÃ¥roht
    Excellent. Just what I needed to know. Have been sitting some hours scratching my head sore. Thanks :-)
  • We are facing the similar situation. When we create the entity, many to many association gets created but when we just try to create the association between already exisitng objects, we get no error and no association gets created. We tried it with flush before and after but of no use.

    -Shailesh
  • paulrene
    I've been stuck on this for 3 days now! Thank you so much for the solution! This should be mentioned in the Hibernate FAQ. I'll drop them a letter.. ;)
  • Marko Novakovic
    My GOD.... Thanks very much.. More than few days of reading official documentation and couldn't find a solution. Thanks again
  • Venushka
    Thank you! You are super!
blog comments powered by Disqus