代码之家  ›  专栏  ›  技术社区  ›  l0st3d

删除Tapestry5给出的休眠实体:“具有相同标识符值的其他对象已与会话关联”[重复]

  •  1
  • l0st3d  · 技术社区  · 15 年前

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

    删除实体时出错。我一次只在一个组中拥有用户,所以在用户类中这是一种多方面的关系。在page类中,我有一个属性组:

    @Property @Persist private Group group;
    

    在页面激活时填充:

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

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

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

    当该组中没有用户时,将执行删除操作,浏览器将重定向到列表页(如预期)。但是,如果组中有用户,则会从休眠中引发异常,并显示消息:

    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方法会将Group对象更改为表示同一实体(同一类、同一ID)的另一个对象。我做错了什么有什么暗示吗?

    3 回复  |  直到 15 年前
        1
  •  3
  •   César Alforde    15 年前

    我认为你应该尝试:

    @Persist("entity")
    

    因为@pesist注释(不带参数)将您的组对象存储在会话中,当您删除它时,它是一个分离的对象。

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

    另一种方法是存储组ID(而不是组对象)并在OnActivate方法中检索该对象。

        2
  •  0
  •   KLE rslite    15 年前

    我不知道挂毯,但在冬眠中…

    当您尝试使用对象A删除实体(对:类和ID)时,会出现此消息,而休眠会话已经具有与此对对应的实例B。

    例如,加载用户将加载实体(可能是惰性的)。因此,要删除组,应该使用Hibernate使用的组实例(确切的Java对象)作为用户组。如果使用另一个实例,则会得到该异常。

        3
  •  0
  •   AlexBottoni    15 年前

    在Tapestry5 wiki上有一个关于这个主题的指南:

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

    高温高压