Hibernate Внешний ключ много-к-одному По умолчанию 0 - PullRequest
6 голосов
/ 13 января 2011

У меня есть таблица, в которой родительский объект имеет необязательное отношение многие-к-одному. Проблема в том, что в таблице по умолчанию для столбца fkey установлено значение 0.

При выборе, используя fetch = "join" и т. Д. - по умолчанию значение 0 для клавиши fkey используется снова и снова для выбора другой таблицы для идентификатора 0. Конечно, этого не существует, но как я могу сказать Hibernate, что значение 0 должно совпадать с NULL - чтобы не повторяться более 20 раз при извлечении несуществующих отношений?

<many-to-one name="device" lazy="false" class="Device" not-null="true" access="field" cascade="none" not-found="ignore">
<column name="DEVICEID" default="0" not-null="false"/>

Ответы [ 3 ]

4 голосов
/ 15 января 2011

Есть два способа сделать это: путь, который может привести к уродливой производительности, и путь, который является болезненным и неловким.

Потенциально уродливый путь сделан на конце ToOne. Используя аннотации Hibernate это будет:

@Entity
public class Foo
{
    ...

    @ManyToOne
    @JoinColumn( name = "DEVICEID" )
    @NotFound( action = NotFoundAction.IGNORE )
    private Device device;

    ...
}

К сожалению, это вызывает упреждающее обращение к базе данных (без отложенной загрузки), потому что устройство может иметь значение null, и если Hibernate создал отложенное устройство, тогда «device == null» никогда не будет иметь значение true.

Другой способ заключается в создании пользовательского типа пользователя, который перехватывает запросы для идентификатора 0 и возвращает для него значение null, а затем присваивает его первичному ключу устройства с помощью @Type. Это вынуждает интерпретацию 0 ~ null для каждого с внешним ключом в Device.

3 голосов
/ 26 января 2011

Мне удалось это исправить, создав тип id-long, который расширяет встроенный тип Long, но если идентификатор, возвращаемый из SQL, был равен 0, вместо него возвращается null. Это сохраняло допустимые значения 0 по умолчанию в нашей БД, в то время как в спящем режиме прекращалось выполнение отложенных выборок.

public class IdentifierLongType extends LongType implements IdentifierType {

@Override
public Object get(ResultSet rs, String name) throws SQLException {
    long i = rs.getLong(name);
    if (i == 0) {
        return null;
    } else {
        return Long.valueOf(i);
    }
}

}

Причиной применения явного значения по умолчанию 0 является то, что Oracle обрабатывает индексирование и нулевые значения странным образом, предлагая лучшую производительность запросов с явными значениями по сравнению с ', где col [не] null'

0 голосов
/ 13 января 2011

Я думаю, вы используете примитивный тип в качестве столбцов первичного / внешнего ключа в вашем объекте.Если да, то попробуйте использовать классы-оболочки.Поскольку у примитивных типов не может быть значений по умолчанию как ноль.

...