Hibernate обрабатывает длинное значение 0 вместо NULL в отношениях ManyToOne

Я использую Hibernate для доступа к устаревшей БД. Для некоторых таблиц целостность ссылок родитель-потомок не применяется, и значение long 0 используется вместо NULL для некоторых «родительских» столбцов в дочерних таблицах, чтобы обозначить «отсутствие родителя».

Я все еще хочу использовать эти отношения в полях @ManyToOne и @OneToMany, но получаю ошибку EntityNotFound, так как значение 0 не соответствует ни одной записи в главной таблице.

Каковы мои варианты?


person Vladimir    schedule 07.11.2011    source источник


Ответы (3)


Используйте аннотацию NotFound:

@NotFound(action = NotFoundAction.IGNORE)

См. http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-manytoone

person JB Nizet    schedule 07.11.2011
comment
Это решает мою проблему. Но я по-прежнему хочу, чтобы Hibernate обеспечивал целостность ссылок для всех ненулевых значений ключа. - person Vladimir; 07.11.2011
comment
Hibernate не обеспечивает целостность ссылок. База данных делает. Ограничение внешнего ключа должно существовать, но это, конечно, невозможно из-за этих нулевых строк. Hibernate не сможет волшебным образом обеспечить ссылочную целостность, которую не может обеспечить даже база данных. Если вы отобразите этот столбец как ассоциацию, я не понимаю, как вы могли бы создать ненулевое значение, указывающее ни на что. - person JB Nizet; 07.11.2011
comment
Это устаревшая БД с недокументированной схемой, и эта ссылка поддерживается проприетарным программным обеспечением. Все, что я знаю на данный момент, это то, что значения 0 разрешены в качестве ключей вместо обычных NULL. Я предполагаю, что эталонная целостность все еще существует для этих отношений и поддерживается проприетарным программным обеспечением, но я хочу, чтобы мне немедленно сообщали, если мое предположение неверно. - person Vladimir; 07.11.2011
comment
Как я уже сказал, если вы сохраните существующий родитель в своем дочернем элементе, Hibernate, конечно, будет использовать идентификатор родителя для заполнения столбца. Поэтому я не понимаю, как вы можете нарушить ссылочную целостность. - person JB Nizet; 07.11.2011
comment
Проприетарное программное обеспечение, а не я, потенциально может сломать код. Я подозреваю это, поскольку не знаю, почему авторы решили не обеспечивать целостность ссылок для некоторых столбцов. Кстати, я пытался добавить аннотацию @NotFound, но, похоже, Hibernate игнорирует ее (в методе AnnotationBinder.processElementAnnotations()). Может быть, аннотации Hibernate, в отличие от аннотаций JPA, должны быть явно включены? - person Vladimir; 07.11.2011
comment
Итак, вы хотите, чтобы Hibernate выдавал исключение для всех неправильных значений, кроме 0. Это правильно? Если да, то у меня нет ответа. Но мне это кажется странным требованием. Почему бы не исправить глючное программное обеспечение? - person JB Nizet; 08.11.2011
comment
Да, вы меня правильно поняли, я хочу, чтобы Hibernate выдавал исключение. Упомянутое программное обеспечение принадлежит крупной софтверной компании, исходного кода нет, и я подозреваю, что авторы рассматривают его как функцию, но в любом случае не как ошибку. Кроме того, аннотация @NotFound была молча проигнорирована, поскольку класс NotFound не был найден в моей среде. - person Vladimir; 08.11.2011
comment
Также вы можете пропустить несоответствия данных, если объект с идентификатором отсутствует (+1, потому что это хорошее решение вашей проблемы) - person ssedano; 08.11.2011

Вместо @JoinColumn можно использовать @JoinFormula. Как это

@JoinFormula(value="CASE the0isNullColumn WHEN 0 THEN NULL ELSE the0isNullColumn END")

Выражение означает, что мы проверяем столбец и, если он равен 0, возвращаем NULL. Тогда спящий режим не ищет связанный объект.

person StanislavL    schedule 06.05.2015

Вы можете сопоставить его с java.lang.Long, значение которого по умолчанию равно null. Или вы можете использовать @PostLoad и обнулить его, если 0. Вы также можете использовать @Formula и игнорировать 0.

@Formula, как написано в их документации можно использовать для join conditions.

Поскольку я не знаю вашей модели данных, предоставление действительного примера сложно. Попробуйте с:

id_fk is not null or id_fk <> 0

блокировать.

Если это не соответствует вашим потребностям, вы можете написать собственный Загрузчик запросов

Если вы используете какое-либо ведение журнала, включите свойство show_sql. И добавьте в свой конфиг файл org.hibernate.sql DEBUG.

person ssedano    schedule 07.11.2011
comment
@Formula требует действительного выражения SQL. Можете ли вы предоставить выражение для замены 0 на NULL? - person Vladimir; 07.11.2011
comment
Сопоставление полей с java.lang.Long — это не то, что мне нужно. Мне нужно, чтобы эти поля были сопоставлены с классом сущности как @ManyToOne. - person Vladimir; 07.11.2011
comment
Я просто не могу заставить работать JoinColumnOrFormula. Я разместил отчет об ошибке здесь hibernate.onjira.com/browse/HHH-6811. Я попробую аннотацию загрузчика, если у меня закончатся другие варианты. - person Vladimir; 08.11.2011
comment
включите журнал и вставьте sql - person ssedano; 08.11.2011