Hibernate多对一外键默认值0

时间:2011-01-13 03:48:54

标签: java hibernate orm many-to-one

我有一个表,其中父对象具有可选的多对一关系。问题是该表被设置为将fkey列默认为0.

当选择时,使用fetch =“join”等 - fkey上的默认值0用来反复尝试从另一个表中选择ID 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 个答案:

答案 0 :(得分:4)

有两种方法可以做到这一点,这种方式可以获得难看的性能以及令人痛苦和尴尬的方式。

潜在的丑陋方式是在ToOne端完成的。使用Hibernate Annotations,它将是:

@Entity
public class Foo
{
    ...

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

    ...
}

不幸的是,这会强制抢先抢占数据库(没有延迟加载),因为设备可能为空,如果Hibernate创建了一个懒惰的设备,那么“device == null”永远不会成为现实。

另一种方法是创建一个自定义UserType,拦截对ID 0的请求并为它们返回null,然后使用@Type将其分配给设备的主键。这会强制对带有外键的每个人进行0~null解释。

答案 1 :(得分:3)

我能够通过创建扩展内置Long类型的id-long类型来修复此问题,但是如果从SQL返回的id为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是[not] null'

答案 2 :(得分:0)

我认为您使用基本类型作为对象中的主键/外键列。如果是,那么尝试使用包装类。因为原始类型不能将默认值设置为null。