你映射(簡體)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="br.com._3988215.model.domain">
<class name="Parent" table="PARENT">
<id name="id">
<generator class="native"/>
</id>
<bag cascade="all,delete-orphan" name="childList">
<key column="PARENT_ID" not-null="false"/>
<one-to-many class="Child"/>
</bag>
</class>
<class name="Child" table="CHILD">
<id name="id" column="CHILD_ID">
<generator class="native"/>
</id>
</class>
</hibernate-mapping>
產生
PARENT
ID
CHILD
CHILD_ID
PARENT_ID
根據你所說的
我希望能有休眠檢測子集已從中刪除父對象,並有行子表從數據庫當
喜歡的東西
Parent parent = session.get(...);
parent.getChildren().clear();
session.update(parent);
你說這工作得很好,因爲你有父對象被更新刪除附加的父實例
現在我們來看看下面的一個(注意Assert.assertNull(second))
public class WhatYouWantTest {
private static SessionFactory sessionFactory;
private Serializable parentId;
private Serializable firstId;
private Serializable secondId;
@BeforeClass
public static void setUpClass() {
Configuration c = new Configuration();
c.addResource("mapping.hbm.3988215.xml");
sessionFactory = c.configure().buildSessionFactory();
}
@Before
public void setUp() throws Exception {
Parent parent = new Parent();
Child first = new Child();
Child second = new Child();
Session session = sessionFactory.openSession();
session.beginTransaction();
parentId = session.save(parent);
firstId = session.save(first);
secondId = session.save(second);
parent.getChildList().add(first);
parent.getChildList().add(second);
session.getTransaction().commit();
session.close();
}
@Test
public void removed_second_from_parent_remove_second_from_database() {
Parent parent = new Parent();
parent.setId((Integer) parentId);
Child first = new Child();
first.setId((Integer) firstId);
/**
* It simulates the second one has been removed
*/
parent.getChildList().add(first);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.update(parent);
session.getTransaction().commit();
session.close();
session = sessionFactory.openSession();
session.beginTransaction();
Child second = (Child) session.get(Child.class, secondId);
Assert.assertNull(second);
session.getTransaction().commit();
session.close();
}
}
可惜,測試不及格。你可以做什麼 ???
Hibernate參考說
擴展(或長)會話 - Hibernate的Session可以從底層的JDBC連接斷開的數據庫事務後已提交,並在發生新的客戶端請求時重新連接。這種模式被稱爲會話每會話,甚至不需要重新連接。自動版本控制用於隔離併發修改,通常不允許會話自動刷新,但明確地說。
免責聲明:我沒有任何使用長時間運行的對話的場景。 Java EE有狀態會話Bean支持長時間運行的對話。但它的支持是JPA(不休眠)
或您可以創建一個替代映射,使您的孩子作爲複合元素。因爲它的生命週期取決於父對象上,你可以依靠的複合元素得到你想要的
創建一個名爲AlternativeParent 類擴展父
public class AlternativeParent extends Parent {}
現在它的映射(注意兒童作爲複合元素是什麼而非純@Entity)
<class name="AlternativeParent" table="PARENT">
<id name="id">
<generator class="native"/>
</id>
<bag name="childList" table="CHILD">
<key column="PARENT_ID" not-null="false"/>
<composite-element class="Child">
<property column="CHILD_ID" name="id"/>
</composite-element>
</bag>
</class>
現在實現了方便equals方法在子類
public boolean equals(Object o) {
if (!(o instanceof Child))
return false;
Child other = (Child) o;
// identity equality
// Used by composite elements
if(getId() != null) {
return new EqualsBuilder()
.append(getId(), other.getId())
.isEquals();
} else {
// object equality
}
}
如果我重構如上圖所示(現在使用AlternativeParent代替)測試用例
@Test
public void removed_second_from_parent_remove_second_from_database() {
AlternativeParent parent = new AlternativeParent();
parent.setId((Integer) parentId);
Child first = new Child();
first.setId((Integer) firstId);
/**
* It simulates the second one has been removed
*/
parent.getChildList().add(first);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.update(parent);
session.getTransaction().commit();
session.close();
session = sessionFactory.openSession();
session.beginTransaction();
Child second = (Child) session.get(Child.class, secondId);
Assert.assertNull(second);
session.getTransaction().commit();
session.close();
}
我看到一個綠色條
你的意思是,加載現有的實體,然後'合併( )'它與分離的實例傳遞給我的API? – 2010-10-27 13:27:31
@ mattb:您可以編寫一個合併集合的邏輯,甚至可以替換以前的集合並設置新集合,但要確保已在您的hbm中添加了標籤。 這個將包含一個簡單的sql刪除查詢來刪除完整的集合,然後再保存一個新集合。或者以其他方式,無論你添加什麼東西,這個sql刪除將會每次被觸發,然後你的集合的新副本將被添加。這可以解決您每次手動更新集合的問題。 –
2010-10-27 13:31:46
不知道我是否喜歡這個解決方案,因爲它需要改變我的使用模式 - 例如添加「」。希望這可以通過單獨的映射來解決。 –
2010-10-31 02:39:38