2012-07-12 24 views
7

Tôi tìm thấy rất nhiều bài viết mà nó được giải thích rằng một trong những nên luôn luôn ghi đè Equals/GetHashCode trên một lớp thực thể NHibernate. Nếu tôi không sử dụng Sets, điều này có thực sự cần thiết không?Có mẫu tại sao Equals/GetHashCode nên được ghi đè trong NHibernate?

Tôi chỉ đơn giản là không thể tìm thấy một mẫu mà nó được hiển thị rằng thiếu Equals/GetHashCode có thể dẫn đến hành vi bất ngờ và sai. Mọi thứ dường như hoạt động hoàn hảo nếu không có chúng. Điều này thực sự kỳ lạ mà mọi người nói điều này là cần thiết nhưng không ai có thể cung cấp một mẫu cho thấy lý do tại sao điều này là cần thiết.

Trả lời

11

Có một số question trên SO gần đây về NHibernate đang chọn N + 1 ngay cả khi fetch được chỉ định. Sự cố was bị thiếu Equals/GetHashCode triển khai.

Liên kết câu trả lời cho một liên kết khác tương tự question.

Đây là another question về lý do đằng sau Equals/GetHashCode ghi đè.

Nhibernate n+1 with ternary relationship. Want the middle entity in the ternary
Nhibernate producing proxy despite HQL fetch
NHibernate: Reasons for overriding Equals and GetHashCode
Why Equals and GetHashCode are so important to NHibernate
Why is it important to override GetHashCode when Equals method is overridden?


Sửa

Bạn không cần phải ghi đè lên tất cả các thời gian. Nó có thể là cần thiết nếu bạn đang sử dụng các phím tổng hợp, nhiều phiên với các thực thể tách rời hoặc các phiên không trạng thái.

Nếu bạn đang làm việc với một phiên duy nhất, NHibernate lưu trữ các thực thể vào bộ nhớ cache cấp đầu tiên bằng cách sử dụng bản đồ nhận dạng. So sánh thực thể trong trường hợp đó được thực hiện bằng cách so sánh các id.

Trong trường hợp ở trên (thực thể tách rời, phiên không quốc tịch), NHibernate so sánh các thực thể thực, chứ không phải id của chúng. Theo mặc định, Object.Equals có tham chiếu bình đẳng. Vì vậy, hai đối tượng bằng nhau nếu chúng trỏ đến cùng một ví dụ. Bạn có thể có hai trường hợp có cùng một danh tính nhưng Object.Equals sẽ trả lại false cho chúng. Điều này trái ngược với Entitydefinition:

Một đối tượng mà không được xác định bởi thuộc tính của nó, mà là bởi một sợi của tính liên tục và bản sắc của nó.

JBoss Hibernate wiki có a good explanation trên EqualsHashCode với vài ví dụ mã.

+0

Điều này dường như chỉ liên quan đến các phím tổng hợp. Chúng tôi không sử dụng chúng. Vì vậy, đây là trường hợp duy nhất Equals/GetHashCOde là cần thiết? Tôi biết ba liên kết cuối cùng bạn đã liên kết. Tôi không thấy có bất kỳ mẫu mã nào tái tạo hành vi sai. – Antineutrino

+0

ID hỗn hợp là một trường hợp. Tôi đã cập nhật câu trả lời của mình với một số văn bản và liên kết đến trang wiki của Hibernate ... –

+0

+1 bộ sưu tập liên kết ấn tượng. –

4

Thực tế, chỉ có một số trường hợp hiếm khi xảy ra tác dụng phụ. Nhưng nếu bạn nhận được chúng, chúng khá tinh tế. Ngoài các khóa chính và khóa từ điển tổng hợp, luôn yêu cầu thực hiện Equals/GetHashCode chính xác.

NH quan tâm đến việc khởi tạo một thực thể chỉ một lần trong bộ nhớ, do đó, so sánh tham chiếu mặc định sẽ hoạt động ... nếu không tải xuống được.

Khi không ghi đè Bằng, bạn gặp vấn đề khi giao dịch với proxy. Luôn có hai trường hợp: proxy và thực thể thực. Cả hai đều đại diện cho cùng một thực thể. Chỉ với phương thức Equals được cài đặt đúng, nó được coi là giống nhau.

+0

OK, vì vậy điều này có nghĩa là nếu tôi không sử dụng các phím tổng hợp hoặc từ điển thì lý do duy nhất là sử dụng thực thể và proxy của nó trong suốt. – Antineutrino

+0

Lý do duy nhất tôi biết. Chúng tôi đã không thực hiện Equals/GetHashCode trong dự án của chúng tôi và không gặp bất kỳ vấn đề nào cho đến khi chúng tôi bắt đầu sử dụng tải chậm. –

+0

Tôi đã thêm một ví dụ vào [bài đăng này] (http://stackoverflow.com/a/5857854/200322) cho thấy mức độ bình đẳng có thể thất bại khá đơn giản. Nếu bạn có một đối tượng được so sánh với một bộ sưu tập được tải chậm, bạn sẽ chạy vào so sánh một proxy với thực thể thực (và bình đẳng tham chiếu mặc định sẽ thất bại!). IMO, không nên "làm điều đó chỉ trong những trường hợp cạnh", bạn nên luôn luôn làm điều đó để tiết kiệm sanity của bạn khi gỡ lỗi những vấn đề này. – TheCloudlessSky

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