2009-02-14 41 views
10

Tôi gặp sự cố khi xóa một mục khỏi danh sách. Danh sách được định nghĩa trong một siêu lớp, nhưng các chú thích Hibernate được áp dụng cho các trình truy cập thuộc tính trong một lớp con. Có hai phương thức trong siêu lớp xử lý danh sách. Phương thức "add" hoạt động tốt, nhưng "remove" không thay đổi. Tôi đã kiểm tra các thiết lập Cascade của mình, và tôi dường như có những điều đúng đắn. Tôi đang làm điều gì đó không thể. Nếu không, tôi có làm gì không chính xác?Hibernate: Xóa mục khỏi Danh sách không tồn tại

Dưới đây là lớp học của tôi:.

@Entity 
abstract class Temporal<T> { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @Version 
    private Integer version = null; 

    @Transient 
    protected List<T> content = new ArrayList<T>(); 

    public void remove(T value) { 
     // business logic ... 
     content.remove(value); 
    } 

    public void add(T value) { 
     // business logic ... 
     content.add(value); 
    } 
} 

@Entity 
@AccessType("property") 
class TemporalAsset extends Temporal<Asset> { 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "temporal") 
    public List<Asset> getContent() { 
     return super.content; 
    } 

    protected void setContent(List<Asset> list) { 
     super.content = list; 
    } 
} 

tôi sử dụng một thể hiện của lớp TemporalAsset như sau (lưu ý rằng tôi chỉ sử dụng "làm mới" phương pháp để chứng minh hành vi trong danh sách này không tồn tại một cách chính xác thậm chí nếu tôi tuôn ra hoặc đóng phiên và mở phiên mới):

temporalAsset.add(value1); 
temporalAsset.getContent().size() == 1; // true 
session.update(temporalAsset); 

session.refresh(temporalAsset); 

temporalAsset.getContent().size() == 1; // true 

temporalAsset.remove(value1); 
temporalAsset.getContent().size() == 0; // true 
session.update(temporalAsset); 

session.refresh(temporalAsset); 

temporalAsset.getContent().size() == 0; // false, its 1 

Cảm ơn.

Trả lời

14

Bạn cần phải xác định rõ ràng thác như CascadeType.DELETE_ORPHAN.

Cố gắng thay đổi mã để

@OneToMany  
@Cascade(cascade = {CascadeType.ALL, CascadeType.DELETE_ORPHAN}, mappedBy = "temporal") 

Phần từ ngủ đông docs:

Nếu tuổi thọ các đối tượng trẻ em được bao bọc bởi tuổi thọ của đối tượng phụ huynh , làm cho cha mẹ đầy đủ đối tượng vòng đời bằng cách chỉ định CascadeType.ALL và org.hibernate.annotations.CascadeType.DELETE_ORPHAN (vui lòng tham khảo hướng dẫn tham khảo Hibernate cho ngữ nghĩa của mồ côi xóa)

+0

Đó là nó! cảm ơn rất nhiều – codefinger

+0

CascadeType.DELETE_ORPHAN không được chấp nhận. Có cách nào khác không? –

+5

sử dụng @OneToOne (orphanRemoval = true) hoặc @OneToMany (orphanRemoval = true) theo http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/annotations/CascadeType.html – FoxyBOA

0

Thử xóa các cuộc gọi đến Session.refresh(). Từ tài liệu:

Đọc lại trạng thái của ví dụ nhất định từ cơ sở dữ liệu cơ bản. Không thể sử dụng điều này để triển khai các phiên chạy dài mà trải qua nhiều tác vụ kinh doanh. Tuy nhiên, phương pháp này hữu ích trong một số trường hợp đặc biệt là . Ví dụ

  • nơi một cơ sở dữ liệu kích hoạt làm thay đổi trạng thái đối tượng khi chèn hoặc cập nhật
  • sau khi thực hiện SQL trực tiếp (ví dụ. Một bản cập nhật khối lượng) trong cùng một phiên
  • sau khi chèn một Blob hoặc CLOB

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Session.html#refresh(java.lang.Object)

Nếu bạn gọi flush() trước khi làm mới(), mà có thể khắc phục vấn đề quá, vì tuôn ra () đảm bảo rằng bất kỳ SQL đang chờ xử lý nào sẽ được thực hiện đối với DB. Trong thực tế, tôi gần như không bao giờ nhìn thấy bất cứ ai sử dụng refresh() và nó không giống như từ mã của bạn mà bạn cần nó.

Chương này từ tài liệu là đáng đọc:

http://www.hibernate.org/hib_docs/v3/reference/en/html/objectstate.html

+0

Tôi chỉ bao gồm làm mới ở đây để minh họa hành vi. Trong thực tế, xả nước không tồn tại những thay đổi trong danh sách. Tôi thậm chí có thể đóng phiên, mở một phiên mới và danh sách vẫn có giá trị trong đó. – codefinger

0

Bạn đã đánh dấu trường 'nội dung' như thoáng qua trong lớp siêu. Tôi ít nhất cũng nghi ngờ rằng điều này đang gây ra vấn đề. Với ánh xạ trong lớp con, về cơ bản bạn có hai ánh xạ mâu thuẫn cho cùng một thuộc tính.

+0

bạn sẽ nghĩ , nhưng điều đó không gây ra bất kỳ vấn đề gì – codefinger

Các vấn đề liên quan