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.
Cảm ơn bạn đã chia sẻ thông tin này với chúng tôi. –
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