冬眠して、多くの外部キーのデフォルト0
-
10-10-2019 - |
質問
親オブジェクトにオプションの多面関係があるテーブルがあります。問題は、テーブルがFKEY列を0にデフォルトするように設定されていることです。
選択するとき、fetch = "join"などを使用する場合、FKEYのデフォルト0のデフォルトは、ID 0の別のテーブルから選択するために何度も試してみてください。もちろん、これは存在しませんが、どうすればよいですか。 0の値をnullと同じと扱うように冬眠します。
<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"/>
解決 2
組み込みの長いタイプを拡張するIDロングタイプを作成することでこれを修正することができましたが、SQLから返されたIDが0の場合、代わりにnullを返します。これにより、DBのデフォルト0の手当が維持され、Hibernateに怠zyなフェッチを止めさせました。
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つの方法があります。パフォーマンスの面で醜い方法と、痛みを伴う方法です。
潜在的に醜い方法は、Toooneの端で行われます。 Hibernate Annotationsを使用してください。
@Entity
public class Foo
{
...
@ManyToOne
@JoinColumn( name = "DEVICEID" )
@NotFound( action = NotFoundAction.IGNORE )
private Device device;
...
}
残念ながら、これはデバイスがnullになる可能性があるため、先制データベースのヒット(怠zyなロードなし)を強制し、hebernateが怠zyなデバイスを作成した場合、「device == null」は決して真実ではありません。
もう1つの方法は、ID 0のリクエストを傍受してそれらのnullを返すカスタムUserTypeを作成し、それをプライマリキーに割り当てることを含みます デバイスの @typeで。これにより、外部キーをデバイスに入れたすべての人の0〜NULL解釈が強制されます。
オブジェクトのプライマリ/外部キー列としてプリミティブタイプを使用していると思います。はいの場合、ラッパークラスを使用してみてください。プリミティブタイプは、nullとしてデフォルト値を持つことができないためです。