Search code examples
javahibernatetapestry

Delete a hibernate entity with tapestry5 gives : "a different object with the same identifier value was already associated with the session"


Possible Duplicate:
Hibernate: different object with the same identifier value was already associated with the session

I have an error being thrown on deleting an entity. I have users in only one group at a time, so it's a ManyToOne relationship on the User class. In the page class I have a property group:

@Property @Persist private Group group;

that is populated on page activation:

public void onActivate(Group g) {
    group = g;
}

When the deletion ActionLink is clicked, this is executed:

@CommitAfter
public ListBillingUserGroups onActionFromDelete() {
    for (User u : getUsersInGroup())
        u.setGroup(null);
    session.delete(group);
    return listPage;
}

public List<User> getUsersInGroup() {
    Criteria c = session.createCriteria(User.class)
        .add(eq("company", ctx.getUser().getCompany()))
        .add(eq("group", group));
    return c.list();
}

When the group has no users in it, then the delete happens, and the browser redirects to the list page (as expected). However, if the group has users in, then I get an exception thrown from hibernate, with message:

a different object with the same identifier value was already associated with the session: [my.package.Group#10]

with a stacktrace:

org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:613)
org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:121)
org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:74)
org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:793)
org.hibernate.impl.SessionImpl.delete(SessionImpl.java:771)
... my code ...

The error still happens if I replace the onActionFromDelete method with:

@CommitAfter
public ListBillingUserGroups onActionFromDelete() {
    for (User u : getUsersInGroup())
        System.out.print(" >> " + u.getGroup());
    session.delete(group);
    return listPage;
}

the error still happens (as opposed to getting the constraint voilation exception), but if I replace it with:

@CommitAfter
public ListBillingUserGroups onActionFromDelete() {
    session.delete(group);
    return listPage;
}

I get the constraint violation exception.

So it behaves as if calling the getAllUsersInGroup method changes the group object to another object representing the same entity (same class, same id). Any hints as to what I am doing wrong ?


Solution

  • I think you should try:

    @Persist("entity")
    

    because the @Pesist annotation (without params) store your Group object in the session and by the time you delete it, is a detached object.

    http://tapestry.apache.org/tapestry5/tapestry-hibernate/userguide.html

    the alternative is to store the Group id (instead of the Group Object) and retrieve the object in the onActivate method.