lập bản đồ của bạn (giản thể)
<?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>
sản xuất
PARENT
ID
CHILD
CHILD_ID
PARENT_ID
Theo những gì bạn nói
Tôi muốn để có thể có Hibernate phát hiện rằng bộ sưu tập con đã bị xóa từ đối tượng phụ huynh, và có các hàng trong bảng con xóa từ cơ sở dữ liệu khi đối tượng cha mẹ được cập nhật
Something như
Parent parent = session.get(...);
parent.getChildren().clear();
session.update(parent);
Bạn nói nó hoạt động tốt bởi vì bạn có một cá thể cha mẹ đính kèm
Bây giờ hãy xem phần sau đây (Thông báo Assert.assertNull (thứ hai))
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();
}
}
Thật không may, kiểm tra không vượt qua. Bạn có thể làm gì ???
- Kích hoạt qua một cuộc nói chuyện dài chạy
Hibernate tài liệu tham khảo cho biết
mở rộng (hoặc dài) Session - Các Hibernate phiên có thể bị ngắt kết nối từ các kết nối JDBC cơ bản sau khi giao dịch cơ sở dữ liệu có đã được cam kết và kết nối lại khi có yêu cầu của ứng dụng khách mới. Mẫu này được gọi là phiên cho mỗi cuộc hội thoại và thậm chí làm cho việc gắn lại không cần thiết. Phiên bản tự động được sử dụng để cô lập các sửa đổi đồng thời và Phiên thường không được phép tự động xóa, nhưng rõ ràng.
tuyên bố từ chối trách nhiệm: tôi không có bất kỳ tình huống nào sử dụng cuộc trò chuyện dài. Các hạt phiên Java Statefulful hỗ trợ cuộc hội thoại dài. Nhưng hỗ trợ của nó là dành cho JPA (không phải Hibernate)
Hoặc bạn có thể tạo ánh xạ thay thế cho phép Con bạn làm thành phần tổng hợp.Bởi vì vòng đời của nó phụ thuộc vào đối tượng phụ huynh, bạn có thể dựa trên các yếu tố tổng hợp để có được những gì bạn muốn
Tạo một lớp có tên AlternativeParent kéo dài Chánh
public class AlternativeParent extends Parent {}
Bây giờ lập bản đồ của mình (Thông báo Child là yếu tố tổng hợp thay vì @Entity đồng bằng)
<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>
Bây giờ thực hiện một thuận tiện bằng phương thức trong lớp Child
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
}
}
Nếu tôi Refactor trường hợp thử nghiệm hiển thị ở trên (Bây giờ bằng cách sử dụng AlternativeParent thay)
@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();
}
tôi nhìn thấy một thanh màu xanh
Bạn có nghĩa là, nạp thực hiện và sau đó 'merge () 'nó với cá thể tách rời được truyền cho tôi API? –
@ mattb: bạn có thể viết logic để hợp nhất bộ sưu tập hoặc thậm chí chỉ cần thay bộ sưu tập trước đó và đặt bộ sưu tập mới, nhưng đảm bảo rằng bạn đã thêm thẻ vào hbm của mình. này sẽ chứa truy vấn xóa sql đơn giản để xóa bộ sưu tập hoàn chỉnh trước khi lưu bộ sưu tập mới. hoặc theo những cách khác, bất cứ ai bạn sẽ thêm bất cứ điều gì, xóa sql này sẽ được kích hoạt mọi lúc và sau đó bản sao mới của bộ sưu tập của bạn sẽ được thêm vào. Điều này có thể giải quyết vấn đề của bạn mỗi khi cập nhật bộ sưu tập theo cách thủ công. –
Không chắc chắn nếu tôi thích giải pháp này, vì nó sẽ yêu cầu thay đổi mẫu sử dụng của tôi - thêm '' ví dụ. Đã hy vọng điều này có thể được cố định với bản đồ một mình. –