【问题标题】:Hibernate's session.update(obj) method makes child objects transient (in parent/child relationship)Hibernate session.update(object) 方法使子对象瞬态(在父/子关系中)
【发布时间】:2011-06-03 04:16:23
【问题描述】:

我有文件夹的父/子关系,如下所示:

一个文件夹可以有 0-1 个父文件夹。 一个文件夹可以有 0-n 个子文件夹(子文件夹)。

使用 Hibernate,我在这些文件夹上调用 session.update(folder)

当这样的文件夹没有子文件夹时,一切正常。

但是当一个文件夹有子文件夹时,session.update(folder) 将使子文件夹瞬态(子文件夹的 id 从 4 变为 0!)。

怎么可能?

这是我的映射文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="test.Folder" table="FOLDERS">

        <id name="id" type="long" access="field">
            <column name="FOLDER_ID" />
            <generator class="native" />
        </id>     

        <set name="childFolders" table="FOLDERS" lazy="false" inverse="true" cascade="none">
            <key column="PARENT_FOLDER_ID" not-null="false"></key>
            <one-to-many class="test.Folder" />
        </set>

        <many-to-one name="parentFolder" column="PARENT_FOLDER_ID" />

        <property name="name" column="FOLDER_NAME" />

        <property name="rootFolder" column="IS_ROOT_FOLDER" type="boolean" not-null="true" />

        <property name="path" column="FOLDER_PATH" />

        <property name="type" column="FOLDER_TYPE" />

        <property name="fullPath" column="FULL_PATH" unique="true" not-null="true" />

    </class>
</hibernate-mapping>

更新:这是我用来更新文件夹的 Java 代码:

public class DatabaseController{

    private SessionFactory  sessionFactory  = null;

    public void updateFolder(Folder folder){
        Session session = null;
        Transaction transaction = null;
        try {
            session = getSession();
            transaction = session.beginTransaction();
            session.update(folder);
            transaction.commit();
        } catch (Exception e) {
            rollback(transaction);
            closeSession();
        } finally {
            closeSession();
        }
    }

    /*
     * Returns the Hibernate session
     */
    private Session getSession() {
        if (_session == null) {
            _session = getSessionFactory().getCurrentSession();
        }
        if (_session.isOpen() == false) {
            _session = getSessionFactory().openSession();
        }
        return _session;
    }

    /**
     * Returns the session factory
     * 
     * @return The session factory
     */
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

【问题讨论】:

  • 请添加您用来更新实体的java代码。

标签: java hibernate


【解决方案1】:

没错

您的集合定义中有 cascade="none"

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-transitive

你需要设置 cascade="save-update"。

【讨论】:

  • 不,我以前有过那套。如果我这样做,Hibernate 首先对父文件夹执行更新,然后将 id=0 设置为子文件夹。然后,它对子文件夹执行 INSERT(而不是 UPDATE),因为 id=0,这将导致 JDBC 异常(重复条目),因为子文件夹已存在于 db 中。
【解决方案2】:

我找到了解决问题的方法。在我的休眠映射文件中更改以下行解决了这个问题:

    <set name="childFolders" table="FOLDERS" inverse="true" cascade="none">
        <key column="PARENT_FOLDER_ID"></key>
        <one-to-many class="test.Folder" />
    </set>

我认为,删除 not-null="false" 的关键就在这里。

【讨论】:

    【解决方案3】:

    您的代码: 更新 2

     <set name="childFolders" table="FOLDERS" lazy="false" inverse="true" cascade="none">
                <key column="PARENT_FOLDER_ID" not-null="false"></key>
                <one-to-many class="test.Folder" /> // **this should point to child table not itself**
      </set>
    

    你提供了错误的关系 我的代码:

    <set cascade="all, delete-orphan" name="childTable" order-by="param" inverse="true">
      <key>
        <column name="p_id"/>
      </key>
      <one-to-many class="com.a.data.ChildTable"/>
    </set>
    

    【讨论】:

    • 你的代码和我的代码除了cascade="xxx"属性有什么不同吗?顺便说一句,更改级联设置没有效果。
    • 抱歉,我没看到。除了类名之外,您的代码中的一对多似乎与我的相同。
    • 我认为你应该先学习hibernate父子关系。see example
    • 我已经读过了。仍然看不到您的代码和我的代码之间的区别。介意一个彻底的解释你指的是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 2013-05-26
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    相关资源
    最近更新 更多