2013-05-31 20 views
5

Tôi đang sử dụng JPA EntityManager để thực hiện một số thao tác và một thao tác như vậy sẽ thay thế một thực thể bằng một thực thể khác có cùng số @Id. Vì vậy, được đưa ra một oldObject và một newObject, cách tốt nhất để loại bỏ các oldObject và thay thế nó bằng newObject là gì?Cách tốt nhất để thay thế một thực thể bằng EntityManager

Dưới đây là một số mã mà không làm việc:

try 
{ 
    entityManager.getTransaction().begin(); 
    entityManager.remove(oldObject); 
    entityManager.persist(newObject); 
    entityManager.getTransaction().commit(); 
} 
catch (PersistenceException persistExc) 
{ 
    entityManager.getTransaction().rollback(); 
    // do some stuff 
} 

Mã này được ngoại lệ sau đây:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.depressio.SomeObject 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678) 

Bây giờ, tất nhiên nó hoạt động OK nếu thay vì loại bỏ các thực thể, tôi chỉ cập nhật các trường đã thay đổi. Tuy nhiên, tôi chỉ được cung cấp đối tượng mới (giao diện người dùng đang ném nó vào tôi qua REST), vì vậy tôi thực sự không có bất kỳ đầu mối nào đã thay đổi, vì vậy tôi phải cập nhật mọi trường. Nếu có một tấn các lĩnh vực, đó không phải là lý tưởng.

Tôi nghĩ tôi hơi bối rối về cách thực sự xóa một cách chính xác. Tôi nghĩ rằng EntityManager.remove là đúng cách, nhưng tôi đoán là không.

Cảm ơn trước!

Chỉnh sửa 1: Tôi cảm thấy tôi nên lưu ý rằng oldObject.id == newObject.id. Các id được tạo ra thông qua một @SequenceGenerator. Tôi có được phép tiếp tục tồn tại các đối tượng có số nhận dạng không nếu từ định danh của họ được chú thích bằng trình tạo đã?

Chỉnh sửa 2: Theo câu trả lời được upvoted hàng đầu here, vì @Id đã được xác định và đó là trường được tạo tự động, Hibernate coi nó được tách ra. Bây giờ tôi biết lý do tại sao Tôi nhận được ngoại lệ, nhưng giải pháp vẫn chưa rõ ràng.

Trả lời

4

Đó là những gì EntityManager.merge() thực hiện. Vượt qua nó, thực thể tách rời mới, và nó sẽ hợp nhất trạng thái của nó với thực thể được đính kèm cũ. Các thực thể tách rời sẽ ở lại tách ra, và cái cũ sẽ ở lại gắn liền, nhưng có trạng thái của nó được thay thế bằng trạng thái của một mới, tách ra.

+0

Ôi trời, thật đáng xấu hổ. Vì một lý do nào đó, tôi cho rằng 'hợp nhất' chỉ làm việc với các thực thể đính kèm, không phải là những thực thể tách rời. Tôi đoán nó có thể làm việc cho cả hai, huh? Dù sao, điều đó giải quyết vấn đề ... thật ngớ ngẩn của tôi. Cảm ơn! – Depressio

+0

việc sáp nhập một thực thể được đính kèm không làm bất cứ điều gì, ngoại trừ việc hợp nhất các kết hợp với các liên kết được chú thích bằng cascade MERGE hoặc ALL. –

+0

Điều gì sẽ xảy ra nếu tôi sửa đổi pháp nhân đính kèm? Tôi thậm chí có phải hợp nhất kể từ khi nó được đính kèm? Tôi có ấn tượng rằng không, tôi không biết. – Depressio