java - 从一对多集合中删除元素(Java + HIbernate + Struts)

标签 java hibernate collections struts

我无法从数据库中删除子对象。从 org.apache.struts.action.Action.execute() 方法中,我从父级的 List 中删除子级,同时调用 session.delete ( child )。我简化了下面的代码,只包含了我认为相关的内容。


hibernate 映射

<class 
    name="xxx.xxx.hibernate.Parent" 
    table="parent">

    ...

    <list
        name="children"
        cascade="all,delete-orphan"
        lazy="true"
        inverse="true">

        <key column="parent_id"/>
        <index column="list_index"/>
        <one-to-many class="xxx.xxx.hibernate.Child"/>
    </list>
</class>

<class 
    name="xxx.xxx.hibernate.Child" 
    table="child">

    ...

    <many-to-one
        name="parent"
        class="xxx.xxx.hibernate.Parent"
        not-null="true"
        column="parent_id" />

</class>


execute() 方法摘录

Transaction tx = session.beginTransaction();  //session is of type org.hibernate.Session

try {
    Parent parent = (Parent) session.get(Parent.class, getParentId());

    Iterator i = form.getDeleteItems().iterator();  //form is of type org.apache.struts.action.ActionForm
    while(i.hasNext()){
        Child child = (Child) i.next();
        session.delete(child);
        parent.getChildren().remove(child); //getChildren() returns type java.util.List
    }

    session.saveOrUpdate(parent);
    tx.commit();
} ...


我试过只用 session.delete(child); 我试过只用 parent.getChildren().remove(child); 和两行,都没有成功。没有错误或抛出的异常或任何类似的东西。我确信这段代码被调用了(我什至使用 System.out.println(); 来跟踪发生了什么),但数据库没有更新。我可以使用类似的代码添加子项,编辑现有子项的非集合属性,编辑父项的属性,所有这些都有效,只是不能删除!

根据Hibernate FAQ我正在做正确的映射,并根据 this SO question我有正确的逻辑。我在 Internet 上到处查看,似乎找不到其他任何东西。

我做错了什么?请帮忙!谢谢。


版本说明

一切都是几年前的事了:

  • Java 1.4.2
  • SQL Server 2005
  • hibernate 3.0.5
  • Struts 1.2.7
  • Apache Tomcat 5.0.28

最佳答案

如果您没有覆盖 equals() 方法,则可能无法在列表中找到该实体,因为它已被分离,现在是一个不同的实例。这就是 remove 不起作用的原因。然后,即使 delete 有效,对象也会重新级联,因为它们仍然存在于集合中。要做的是:

  • 要么覆盖 equals()(和 hashCode())方法,要么使用 id(简单)或一些业务键排序(更合适)(搜索 stackoverflow 以获取覆盖这两个方法的提示),并仅保留 getChildren().remove(child)
  • 在第一个循环中迭代子集合,如下所示:

    Iterator<Child> i = form.getDeleteItems().iterator();
    while(i.hasNext()){
        Child child = i.next();
        for (Iterator<Child> it = parent.getChildren().iterator();) {
             if (child.getId().equals(it.next().getId()) {
                 it.remove(); // this removes the child from the underlying collection
             }
        }
    }
    

关于java - 从一对多集合中删除元素(Java + HIbernate + Struts),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2024078/

相关文章:

java - HashSet 和 LinkedHashSet

java - 在 Java SE 中的 g.drawString 中换行

java - 一对多单向父子ID级联保存

java - 如何将字符串从 OnStartCommand 传递到 IntentService 中的 OnHandleIntent?

hibernate - 如何使用 Hibernate Criteria 添加复杂的订单?

java - Spring 启动和 hibernate 。自动创建日期

java - 在 Java 中对集合进行连接和分离的最佳方法

c# - 遍历强类型泛型 List<T> 的最佳方法是什么?

java - 是否有任何公开可用的 Java 集合单元测试?

java - Android Studio 在重新启动时显示错误