2012-07-01 30 views
9

Tôi đã tìm thấy vấn đề với việc sử dụng kiểu nguyên thủy làm đối tượng @Id cho JPA kết hợp với dữ liệu Spring JPA. Tôi có mối quan hệ cha/con với Cascade.ALL ở phía cha mẹ và con có PK cùng lúc cũng là FK của cha mẹ.Luôn sử dụng trình bao bọc đối tượng nguyên thủy cho JPA @Id thay vì loại nguyên thủy?

class Parent { 
    @Id 
    private long id; 

    @OneToOne(mappedBy = "parent", cascade = ALL) 
    private Child child; 
} 

class Child { 
    @Id 
    @OneToOne 
    private Parent parent; 
} 

Vì vậy, khi tôi chạy:

... 
Parent parent = new Parent(); 
Child child = new Child(parent); 
parent.setChild(child); 
em.persist(parent) 
... 

tất cả mọi thứ hoạt động tốt. Nhưng tôi sử dụng Spring liệu JPA để tồn tại các tổ chức nào, vì vậy tôi chạy thay vì:

parentRepository.save(parent); // instead of em.persist(parent); 

và điều này đã thất bại với các ngoại lệ sau đây:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent 

Vấn đề là liệu Xuân JPA tiết kiệm () Phương pháp kiểm tra xem thực thể có mới hay không và nếu nó là mới thì em.persist() được sử dụng nếu không em.merge() được sử dụng.

Phần thú vị ở đây cách kiểm tra mùa xuân dù thực thể là mới hay không:

getId(entity) == null; 

Và, tất nhiên, điều này là sai lầm, bởi vì tôi đã sử dụng lâu như các loại cho @ id, và giá trị mặc định cho dài là 0. Khi tôi thay đổi lâu dài tất cả mọi thứ làm việc với Spring JPA dữ liệu cũng.

Vì vậy, thực hành được khuyến nghị luôn sử dụng trình bao bọc đối tượng cho các kiểu nguyên thủy (như Long thay vì dài) thay vì các kiểu nguyên thủy. Bất kỳ tài nguyên bên thứ ba nào mô tả điều này như là phương pháp được khuyến nghị sẽ rất hay.

+0

Cảm ơn bạn đã chia sẻ thông tin này với chúng tôi. –

+0

có thể trùng lặp của [Nguyên thủy hoặc bao bọc cho khóa chính ngủ đông] (http://stackoverflow.com/questions/3535791/primitive-or-wrapper-for-hibernate-primary-keys) – stevedbrown

Trả lời

12

Tôi muốn nói có, bạn nên sử dụng loại đối tượng thay vì nguyên thủy vì trường hợp bạn đang thấy. Không có cách nào để phân biệt nếu thực thể là mới hoặc có sẵn với một định danh nguyên thủy. Tôi đã sử dụng ngủ đông trong nhiều năm và tôi luôn sử dụng các đối tượng để nhận dạng.

+1

+1, hoàn toàn đồng ý – Raman

0

Tôi sẽ sử dụng loại đối tượng. Trong ánh xạ xml, bạn có thể đặt một thuộc tính "chưa lưu giá trị", nhưng tôi không nghĩ rằng có một bản dịch trực tiếp cho các chú thích cho việc này. Kết quả là, nó an toàn hơn để gắn bó với các loại đối tượng.

Và hầu hết các lập trình viên sẽ mong đợi một giá trị "null" trong số nhận dạng có nghĩa là chưa được lưu.

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