Нет, я не думаю, что вы упускаете что-то фундаментальное. «Основная причина» проблемы с использованием идентификатора базы данных для equals и hashCode заключается в том, что сгенерированный Hibernate ID хранится в изменяемом поле, и значение этого поля изменяется, когда Hibernate назначает идентификатор. Equals и hashCode должны основываться на неизменяемом состоянии, как описано в разделе «100» * Odersky / Spoon / Venners о написании методов equals / hashCode. Это означает, среди прочего, что вы не можете добавить экземпляр в набор или сравнить его с другим экземпляром до тех пор, пока он не будет сохранен, когда hashCode станет фиксированным.
Единственное, что вам может не хватать, это то, как сложно отслеживать, когда назначается идентификатор, поскольку это делается автоматически в Hibernate. Конечно, вы никогда не могли бы вызвать setId(someNewId)
, но вы могли бы выполнить запрос, который вызывает сброс сеанса, и целая группа временных объектов, не связанных с запросом, внезапно меняла свои идентификаторы с нуля на не-ноль.
Использование бизнес-ключа для equals и hashCode часто рекомендуется сообществом Hibernate, но этот подход также страдает от той же проблемы изменяемого до инициализации. Если ваша сущность является членом постоянного набора, который активно загружается Hibernate, то его можно добавить в набор до инициализации его полей, поэтому hashCode, основанный на этих полях, также не работает. См. Отчет об ошибке гибернации , где обсуждается проблема с равенством бизнес-ключей.
James Brundege рекомендует назначить идентификатор в коде приложения, чтобы избежать этой проблемы. У Ланса Арлауса аналогичный подход с использованием фабрики объектов, которая присваивает идентификаторы.
Если вы действительно хотите использовать автоматически сгенерированный идентификатор для equals и hashCode, рассмотрите возможность использования Assert.notNull(id)
в ваших реализациях equals и hashCode для обнаружения ошибок кодирования.
См. Также еще один стекопоток вопрос с большим количеством дискуссий о различных подходах.