Тут відбулися певні дискусії щодо об'єктів JPA та які hashCode()/ equals()впровадження слід використовувати для класів об'єктів JPA. Більшість із них (якщо не всі) залежать від сплячого режиму, але я хотів би обговорити їх реалізацію JPA нейтрально (я, до речі, використовую EclipseLink).
Усі можливі реалізації мають свої переваги та недоліки щодо:
hashCode()/equals()відповідність договору (незмінність) дляList/Setоперацій- Чи можна виявити однакові об'єкти (наприклад, з різних сеансів, динамічні проксі-сервери з ліниво завантажених структур даних)
- Чи правильно вони поводяться у відстороненому (або непостійному) стані
Наскільки я бачу, є три варіанти :
- Не перекривляйте їх; покладатися на
Object.equals()іObject.hashCode()hashCode()/equals()робота- не вдається ідентифікувати однакові об'єкти, проблеми з динамічними проксі
- немає проблем з відокремленими сутностями
- Замініть їх на основі первинного ключа
hashCode()/equals()ламаються- правильна особистість (для всіх керованих організацій)
- проблеми з відокремленими сутностями
- Замініть їх на основі Business-Id (поля не первинного ключа; що з іноземними ключами?)
hashCode()/equals()ламаються- правильна особистість (для всіх керованих організацій)
- немає проблем з відокремленими сутностями
Мої запитання:
- Я пропустив варіант та / або про / con пункт?
- Який варіант ви вибрали і чому?
ОНОВЛЕННЯ 1:
До « hashCode()/ equals()зламані», я маю в виду , що послідовні hashCode()виклики може повертати різні значення, що (при правильній реалізації) не порушувати в сенсі Objectдокументації API, але викликає проблеми при спробі отримати змінені суті з Map, Setабо інших хеш на основі Collection. Отже, реалізація JPA (принаймні, EclipseLink) не працюватиме належним чином у деяких випадках.
ОНОВЛЕННЯ 2:
Дякую за відповіді - більшість із них мають неабияку якість.
На жаль, я все ще не впевнений, який підхід буде найкращим для застосування в реальному житті або як визначити найкращий підхід для моєї програми. Отже, я буду тримати питання відкритим і сподіваюся на ще кілька дискусій та / або думок.
hashcode()одного і того ж об’єкта об'єкта повинен повернути те саме значення, якщо не equals()змінюються поля, використані в реалізації. Іншими словами, якщо у вашому класі три поля, а ваш equals()метод використовує лише два з них для визначення рівності екземплярів, ви можете розраховувати, що hashcode()повернене значення зміниться, якщо ви зміните одне з цих значень поля - що має сенс, якщо врахувати що цей примірник об'єкта вже не "дорівнює" значенню, яке представляв старий екземпляр.
