2011-01-02 13 views
5

Tôi đang sử dụng triển khai JPA2 và Hibernate.Xóa khỏi bảng có chú thích @OneToOne

Tôi đã có bản đồ đơn giản như thế này:

@Entity 
class Topic { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 

    int id; 

    @OneToOne(cascade = ALL) 
    @JoinColumn(name = "id_poll") 
    private Poll poll; 

} 

@Entity 
class Poll { 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    int id; 
} 

Bây giờ, khi tôi xóa một đối tượng Thăm dò ý kiến ​​đó cũng là trong Topic tôi nhận được một lỗi.

java.sql.SQLException: Liêm chế bảng FKCC42D924982D3F4B vi phạm: [? Xóa từ các cuộc thăm dò nơi id =] CHỦ ĐỀ trong bản Tuyên Bố

Tôi hiểu rằng đó là vì tôi không thể xóa hồ sơ Thăm dò ý kiến nếu nó có tham chiếu trong bảng khác. Làm thế nào tôi có thể giải quyết vấn đề này? Tôi có phải tự thiết lập poll = null trong một bảng Topic hay là có một giải pháp tốt hơn?

Trả lời

5

này được mong đợi:

Một vấn đề thường gặp với các mối quan hệ hai chiều là ứng dụng cập nhật một bên của mối quan hệ, nhưng ở phía bên kia không nhận được cập nhật, và trở thành đồng bộ. Trong JPA, như trong Java nói chung, nó là trách nhiệm của ứng dụng hoặc mô hình đối tượng để duy trì mối quan hệ .

Nguồn: Object corruption, one side of the relationship is not updated after updating the other side

Các địa điểm chính xác để xử lý này là trong một callback @PreRemove:

@Entity 
class Poll { 

    ... 

    @PreRemove 
    private void preRemove() { 
     Poll poll = topic.getPoll(); 
     topic.setPoll(null); 
    } 
} 

Xem thêm: Have JPA/Hibernate to replicate the “ON DELETE SET NULL” functionality

1

Dường như chú thích @OneToOne trong JPA 2 có chứa cờ orphanRemoval, bạn có thể thử đặt điều đó và xem liệu nó có xóa nó một cách duyên dáng hay không.

+1

nope, tôi đã cố gắng này và nó vẫn doesn' t làm việc .. Tôi vẫn có lỗi tương tự .. – Dawid

1

Tôi không thể tìm thấy giải pháp ngay bây giờ, vì vậy trước khi tôi xóa đối tượng Thăm dò ý kiến, tôi luôn nhận được đối tượng Chủ đề chứa Hồ bơi đã cho và đặt thành giá trị rỗng.

Topic topic = entityManager.find(Topic.class, 1); 
Poll poll = topic.getPoll(); 
topic.setPoll(null); 
entityManager.remove(poll); 

Và nó hoạt động chính xác.

0

Vấn đề nằm ở thực tế là bạn đang sử dụng ID được tạo tự động ở cả hai bên. Khi bạn vẫn duy trì thực thể cha, thực thể con cũng được duy trì nhưng ID của nó bên trong thực thể cha mẹ không được cập nhật với thực thể được tạo ra từ cơ sở dữ liệu.

Kết quả là khi bạn xóa phụ huynh, bạn sẽ không xóa đứa trẻ, vì đứa trẻ không có ID.

Thử đặt thủ công ID của thực thể con và orphanRemoval sẽ hoạt động. hành vi