Vì vậy, bạn muốn:
User u1 = new User("Bill");
session.save(u1);
User u2 = new User("Bill");
session.saveOrUpdate(u2);
để nhận thấy rằng u1 và u2 đều giống nhau Bill và chỉ lưu trữ nó một lần? Hibernate không có cách nào để biết rằng Bills là cùng một người. Nó chỉ nhìn vào id của User u2, thấy rằng nó không được thiết lập, kết luận rằng u2 nên được chèn vào, cố gắng và báo cáo một ngoại lệ.
SaveOrUpdate vẫn tồn tại cả đối tượng hoàn toàn mới và đối tượng được tải hiện được đính kèm với phiên. Vì vậy, các công trình này (giả sử bạn có một phương pháp findByName đâu đó và có thuộc tính khác, giả sử favoriteColor):
User u1 = new User("Bill");
u1.setFavoriteColor("blue");
session.saveOrUpdate(u1);
User u2 = findByName("Joe");
u2.setFavoriteColor("red");
session.saveOrUpdate(u2);
Nhưng đó không phải là những gì bạn muốn, phải không?
Vấn đề của bạn được thực hiện tồi tệ hơn bởi thực thể của bạn có khóa chính thay thế và, riêng biệt, khóa doanh nghiệp (được thực thi thông qua ràng buộc duy nhất). Nếu bạn không có một trường id và chỉ đặt tên là khóa chính, bạn có thể sử dụng kết hợp() (cho một cuộc thảo luận về saveOrUpdate vs merge, look here):
User u1 = new User("Bill");
u1.setFavoriteColor("blue");
session.save(u1);
User u2 = new User("Bill");
u2.setFavoriteColor("red");
u2 = session.merge(u2);
Nhưng bạn không có điều đó, bạn cần phải thực thi cả ràng buộc PK trên id và tính duy nhất trên tên. Vì vậy, bạn sẽ cần một số biến thể của hợp nhất mà làm điều đó.Rất gần, bạn muốn một cái gì đó dọc theo các dòng sau:
public User mergeByName(User user) {
User merged;
User candidate = findByName(user.getName());
if (candidate != null) {
user.setId(candidate.getId());
merged = session.merge(user);
} else {
session.save(user);
merged = user;
}
return merged;
}
Thx vì sự tin cậy của bạn. 'id' là khóa chính và' name' có constriant độc đáo Chúng tôi có lớp đối tượng Người dùng ví dụ: 'Hóa đơn người dùng = new User()' và thuộc tính về hóa đơn chúng tôi nhận được từ keybord hoặc trang web. : Làm thế nào bạn có thể thực hiện saveOrUpdate() có nghĩa là nếu bill.name tồn tại trong db, chúng tôi gọi update() nếu không chúng tôi lưu hóa đơn. – kunkanwan