Đã có một số cuộc thảo luận ở đây về các thực thể JPA và nên sử dụng hashCode()
/ equals()
triển khai cho các lớp thực thể JPA. Hầu hết (nếu không phải tất cả) trong số họ phụ thuộc vào Hibernate, nhưng tôi muốn thảo luận về họ về mặt thực thi JPA (tôi đang sử dụng EclipseLink).
Tất cả các triển khai có thể có những ưu điểm và nhược điểm riêng liên quan đến:
hashCode()
/equals()
sự phù hợp hợp đồng (bất biến) choList
/Set
hoạt động- Cho dù các đối tượng giống hệt nhau (ví dụ từ các phiên khác nhau, các proxy động từ cấu trúc dữ liệu được tải nhanh) có thể được phát hiện
- Liệu các thực thể có hành xử đúng trong trạng thái tách rời (hoặc không tồn tại)
Theo tôi có thể thấy, có ba lựa chọn :
- Đừng ghi đè lên chúng; dựa vào
Object.equals()
vàObject.hashCode()
hashCode()
/equals()
công việc- không thể xác định các đối tượng giống hệt nhau, các vấn đề với proxy động
- không có vấn đề với các thực thể tách rời
- Ghi đè chúng, dựa trên khóa chính
hashCode()
/equals()
bị hỏng- danh tính chính xác (cho tất cả các thực thể được quản lý)
- vấn đề với các thực thể tách ra
- Ghi đè chúng, dựa trên Id doanh nghiệp (các trường khóa không chính; còn khóa ngoại thì sao?)
hashCode()
/equals()
bị hỏng- danh tính chính xác (cho tất cả các thực thể được quản lý)
- không có vấn đề với các thực thể tách rời
Câu hỏi của tôi là:
- Tôi đã bỏ lỡ một tùy chọn và / hoặc pro / con point?
- Lựa chọn nào bạn đã chọn và tại sao?
CẬP NHẬT 1:
Bằng cách " hashCode()
/ equals()
bị phá vỡ", tôi có nghĩa là tiếp hashCode()
lời gọi có thể trả về giá trị khác nhau, đó là (khi thực hiện một cách chính xác) không bị hỏng theo nghĩa của Object
tài liệu API, nhưng mà gây ra vấn đề khi cố gắng để lấy một thực thể đã thay đổi từ một Map
, Set
hoặc khác dựa trên hàm băm Collection
. Do đó, các triển khai JPA (ít nhất là EclipseLink) sẽ không hoạt động chính xác trong một số trường hợp.
CẬP NHẬT 2:
Cảm ơn bạn đã trả lời của bạn - hầu hết trong số họ có chất lượng đáng chú ý.
Thật không may, tôi vẫn không chắc chắn cách tiếp cận nào sẽ là tốt nhất cho ứng dụng thực tế hoặc làm thế nào để xác định cách tiếp cận tốt nhất cho ứng dụng của tôi. Vì vậy, tôi sẽ giữ câu hỏi mở và hy vọng có thêm một số thảo luận và / hoặc ý kiến.
hashcode()
cùng một đối tượng sẽ trả về cùng một giá trị, trừ khi bất kỳ trường nào được sử dụng trong việc equals()
thực hiện thay đổi. Nói cách khác, nếu bạn có ba trường trong lớp và equals()
phương thức của bạn chỉ sử dụng hai trường để xác định đẳng thức của các thể hiện, thì bạn có thể mong đợi hashcode()
giá trị trả về sẽ thay đổi nếu bạn thay đổi một trong các giá trị của trường đó - điều này hợp lý khi bạn xem xét rằng đối tượng này không còn "bằng" với giá trị mà thể hiện cũ thể hiện.