简体   繁体   English

Hibernate多对一外键默认值0

[英]Hibernate Many-To-One Foreign Key Default 0

I have a table where the the parent object has an optional many-to-one relationship. 我有一个表,其中父对象具有可选的多对一关系。 The problem is that the table is setup to default the fkey column to 0. 问题是该表被设置为将fkey列默认为0。

When selecting, using fetch="join", etc-- the default of 0 on the fkey is being used to try over and over to select from another table for the ID 0. Of course this doesn't exist, but how can I tell Hibernate to treat a value of 0 to be the same as NULL-- to not cycle through 20+ times in fetching a relationship which doesn't exist? 当选择时,使用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"/>

There are two ways of doing this, the way that can get ugly performance-wise and the way that is painful and awkward. 有两种方法可以做到这一点,可以获得丑陋的表现方式以及痛苦和尴尬的方式。

The potentially ugly way is done on the ToOne end. 可能很丑陋的方式是在ToOne端完成的。 Using Hibernate Annotations it would be: 使用Hibernate Annotations它将是:

@Entity
public class Foo
{
    ...

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

    ...
}

Unfortunately, this forces a preemptive database hit (no lazy loading) because device can be null, and if Hibernate created a lazy Device then "device == null" would never be true. 不幸的是,这会强制抢占数据库命中(没有延迟加载),因为设备可以为null,如果Hibernate创建了一个惰性设备,那么“device == null”将永远不会成立。

The other way involves creating a custom UserType that intercepts requests for the ID 0 and returns null for them, and then assigning that to the primary key of Device with @Type. 另一种方法涉及创建一个自定义UserType,它拦截对ID 0的请求并为它们返回null,然后将其分配给具有@Type 的Device的主键。 This forces the 0 ~ null interpretation on everyone with a foreign key into Device. 这会强制对带有外键的每个人进行0~null解释。

I was able to fix this by creating an id-long type which extends the built in Long type, but if the id returned from SQL was 0, return null instead. 我能够通过创建一个扩展内置Long类型的id-long类型来解决这个问题,但是如果从SQL返回的id为0,则返回null。 This kept the allowance of default 0s in our DB while getting hibernate to stop doing lazy fetches. 这使我们的数据库中的默认值为0,同时让hibernate停止执行延迟提取。

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);
    }
}

} }

The reason for enforcing explicit default 0 is that Oracle handles indexing and null values oddly, suggesting better query performance with explicit values vs. 'where col is [not] null' 强制显式默认值0的原因是Oracle奇怪地处理索引和空值,建议使用显式值与'其中col是[not] null'的查询性能更好

I think you are using primitive type as your primary/foreign key columns in your object. 我认为您使用原始类型作为对象中的主键/外键列。 If yes then try using wrapper classes. 如果是,那么尝试使用包装类。 Because primitive types can't have default values as null. 因为基元类型不能将默认值设置为null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM