MiKo
MiKo

Reputation: 2146

Hibernate: delete many-to-many association

I have two tables with the many-to-many association.

— DB fragment:

loads
Id
Name

sessions
Id
Date

sessionsloads
LoadId
SessionId

— Hibernate mapping fragments:

/* loads.hbm.xml */
<set name="sessions" table="sessionsloads" inverse="true">
    <key column="LoadId" />
    <many-to-many column="SessionId" class="Session" />
</set>
…
/* sessions.hbm.xml */
<set name="loads" table="sessionsloads">
    <key column="SessionId" />
    <many-to-many column="LoadId" class="Load" />
</set>

In order to remove one entry from the association table sessionsloads, I execute this code:

Session session = sessionDao.getObject(sessionId);
Load load = loadDao.getObject(loadId);

load.getSessions().remove(session);
loadDao.saveObject(load);

But, after launching, this code change nothing.

What's the right way to remove an association?

Upvotes: 10

Views: 16815

Answers (2)

Affe
Affe

Reputation: 47954

Looks like you just need to turn on Transitive persistence (e.g., cascade=all-delete-orphan for "full" transitive.)

-- Edit Thanks for the upvote, althugh Pascal was accurate in that cascade alone is not enough to fix the original problem, but that both sides of the relationship weren't being managed. Teach me to answer hastily :)

--

Also, an Entity named Session broke my brain :(

Upvotes: 5

Pascal Thivent
Pascal Thivent

Reputation: 570315

You need to update both sides of the link between Load and Session:

Session session = sessionDao.getObject(sessionId);
Load load = loadDao.getObject(loadId);

load.getSessions().remove(session);
session.getLoads().remove(load);
loadDao.saveObject(load);

Actually, many developer use defensive methods to manage bi-directional associations. For example on Load, you could add the following methods:

public void removeFromSessions(Session session) {
    this.getSessions().remove(session);
    session.getLoads().remove(this);
}
public void addToSessions(Session session) {
    this.getSessions().add(session);
    session.getLoads().add(this);
}

Upvotes: 16

Related Questions