use*_*648 6 java orm hibernate 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"/>
Run Code Online (Sandbox Code Playgroud)
有两种方法可以做到这一点,一种是在性能方面变得丑陋的方式,另一种是痛苦和尴尬的方式。
潜在的丑陋方式是在 ToOne 端完成的。使用 Hibernate Annotations 将是:
@Entity
public class Foo
{
...
@ManyToOne
@JoinColumn( name = "DEVICEID" )
@NotFound( action = NotFoundAction.IGNORE )
private Device device;
...
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会强制进行抢占式数据库命中(无延迟加载),因为设备可以为空,并且如果 Hibernate 创建了一个延迟设备,那么“device == null”永远不会为真。
另一种方法是创建一个自定义 UserType,它拦截对 ID 0 的请求并为它们返回 null,然后将其分配给带有 @Type的 Device的主键。这会强制对每个有外键的人进行 0 ~ null 解释到 Device 中。
我可以通过创建一个扩展内置 Long 类型的 id-long 类型来解决此问题,但如果从 SQL 返回的 id 为 0,则返回 null。这在我们的数据库中保留了默认的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
}
强制执行显式默认值 0 的原因是 Oracle 处理索引和空值的方式很奇怪,这表明使用显式值比“where col is [not] null”有更好的查询性能