В CUBA сущности тем или иным образом наследовали BaseGenericIdEntity, где были equals() и hashCode() в которых для вычисления брался id. Всё было понятно и ожидаемо.
В JMIX сущности мы аннотируем, не наследуем. И со “своими” сущностями всё понятно, я могу переопределить equals() и hashCode(). Но как быть с “системными”, например, RoleAssignmentEntity? Ни HashSet, ни HashMap “нормально” с ними не получиться организовать?
Возможно я ошибаюсь, но как я понимаю, когда вы добавляете аннотацию JmixEntity, jmix скрыто (видимо при компиляции) обновляет методы. К примеру в сеттеры добавляется листенер на обновление компонентов в ui. Так и equals с hashCode обновляются.
Можете найти класс: EntityEntry, посмотреть классы что от него отнаследованы.
Там вроде как все сущноcти jmix.

Здравствуйте, Евгений!
Как верно указал Ярослав, equals и hashCode добавляются автоматически. Это происходит в jmix-плагине для gradle во время энхансинга сущностей.
Самостоятельно определять equals и hashCode в сущностях крайне нежелательно, поскольку при вмешивании в них бизнес логики или другом неаккуратном использовании это может нарушить работу внутренних механизмов, т.е. как раз сломать их хранение и обработку в контексте, где используются HashSet и HashMap.
Так же как и в CUBA, в Jmix эти методы полагаются на id, т.е. equals должен возвращать true тогда и только тогда, когда сравниваются два клона одного и того же экземпляра сущности, какие бы изменения в каждом из них не находились, что и реализовано в io.jmix.core.impl.EntityInternals#equals.
С уважением,
Дмитрий