2011-05-30 21 views
1

我的文件夾對家長/孩子的關係,這看起來是這樣的:Hibernate的了Session.update(OBJ)方法使子對象的瞬態(在父/子關係)

一個文件夾可以有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; 
    } 
} 
+0

請添加您用來更新實體的java代碼。 – Augusto 2011-05-30 12:55:37

+0

@Augusto我添加了代碼 – Timo 2011-06-01 21:24:41

回答

0

我找到了一個解決問題的辦法。更改以下行中我的Hibernate映射文件解決了該問題:

<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"爲重點的伎倆。

0

這是正確的

你有級聯=「無」在您的設置定義。

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

您需要設置級聯= 「保存更新」。

+0

不,我之前設置過。如果我這樣做,Hibernate首先對父文件夾執行UPDATE,然後將id = 0設置爲子文件夾。然後,它爲子文件夾(而不是UPDATE)執行INSERT,因爲id = 0,這將導致JDBC異常(重複條目),因爲子文件夾已經存在於數據庫中。 – Timo 2011-06-01 21:24:01

-1

代碼: 更新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> 
+0

除了cascade =「xxx」屬性之外,您的代碼和我的代碼之間的區別在哪裏?順便說一下,改變級聯設置沒有效果。 – Timo 2011-05-30 14:52:34

+0

@valmar請參閱'' – 2011-05-30 15:01:51

+0

對不起,但我沒看到它。代碼中的一對多看起來和我的一樣,除了類名。 – Timo 2011-05-30 15:24:32