使用tapestry5删除一个hibernate实体给出:“具有相同标识符值的另一个对象已经与会话关联”

时间:2009-09-07 16:04:17

标签: java hibernate tapestry

  

可能重复:
  Hibernate: different object with the same identifier value was already associated with the session

我在删除实体时遇到错误。我一次只有一个组中的用户,因此它是User类上的ManyToOne关系。在页面类中,我有一个属性组:

@Property @Persist private Group group;

在页面激活时填充:

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

单击删除ActionLink时,将执行以下操作:

@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();
}

当该组中没有用户时,则会发生删除,并且浏览器会重定向到列表页面(如预期的那样)。但是,如果该组中有用户,则会从hibernate中抛出异常,并显示消息:

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

使用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 ...

如果我将onActionFromDelete方法替换为:

,则仍会出现错误
@CommitAfter
public ListBillingUserGroups onActionFromDelete() {
    for (User u : getUsersInGroup())
        System.out.print(" >> " + u.getGroup());
    session.delete(group);
    return listPage;
}

错误仍然发生(与获取约束声音异常相反),但如果我将其替换为:

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

我得到了约束违规例外。

因此,它的行为就像调用getAllUsersInGroup方法将组对象更改为表示同一实体的另一个对象(相同的类,相同的id)。关于我做错了什么提示?

3 个答案:

答案 0 :(得分:3)

我认为你应该尝试:

@Persist("entity")

因为@Pesist注释(没有参数)将您的Group对象存储在会话中,并且当您删除它时,它是一个分离的对象。

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

替代方法是存储组ID(而不是组对象)并在onActivate方法中检索对象。

答案 1 :(得分:0)

我不知道Tapestry,但是在Hibernate ......

当您尝试使用对象A删除实体(pair:class和id)时会出现此消息,而Hibernate会话已经有一个与该对对应的实例B.

例如,加载用户会加载实体(可能是懒惰的)。因此,要删除组,您应该使用Hibernate作为用户组使用的组实例(确切的Java对象)。如果您使用其他实例,您将获得该异常。

答案 2 :(得分:0)

在Tapestry5 Wiki上有一个关于这个主题的方法:

http://wiki.apache.org/tapestry/Tapestry5AvoidingDifferentObjectWithSameIDExceptions

HTH