オブジェクトツーオブジェクトマッピングなしで外部キーを実施することは可能ですか?
-
22-09-2019 - |
質問
次のマッピングが提供されていると仮定します。
<class name="A" table="a_table">
<id name="id"/>
<many-to-one name="entityB" column="fk_B" not-null="false" unique="true"/>
</class>
<class name="B" table="b_table">
<id name="id"/>
</class>
Javaクラス:
public class A {
private long id;
private B entityB;
// getters and setters skipped
}
冬眠マッピングを変更することは可能ですか 外部キーはまだスタートアップ時に冬眠によって実施され、作成されています, 、しかしクラス A
次のように見えます:
public class A {
private long id;
private long idOfB;
// getters and setters skipped
}
変換すればそれを理解しています <many-to-one...
に <property...
これは機能しますが、外部キーはデータベースによって実施されません。
オブジェクトのためにこれを行う必要があります B
時々原因となる可能性があります(またはそうでない可能性があります)org.hibernate.LazyInitializationException: could not initialize proxy - no Session
場合に発生する例外 a.getB()
呼ばれています。私はそれをasとして持ちたいと思います long idOfB
必要なときはいつでもオブジェクト全体をロードします。これにより、オブジェクトの負荷も作成されます A
より速い。
私の質問は非常に似ていると思います これです, 、しかし、私の場合、私が電話しても、提供されたソリューション(怠zyなロードを使用する)は適切ではありません a.getB().getId()
, 、私は得るでしょう LazyInitializationException
一方、私が電話した場合 a.getIdOfB()
私はしません。
よろしくお願いします。
解決
言われるように
変換すればそれを理解しています しかし、外部キーは施行されません データベースによって。
だから私のアドバイスは次のとおりです。 両方を使う
public class EntityA {
private Integer idOfB;
private EntityB entityB;
// getter's and setter's
}
と
<class name="A" table="a_table">
<id name="id"/>
<property name="idOfB" column="fk_B" not-null="false" unique="true"/>
<many-to-one name="entityB" update="false" insert="false" column="fk_B"/>
</class>
2つのプロパティが同じ列を共有している場合に注意してください。 あなたはそれについて設定を1つのプロパティに置く必要があります. 。それ以外の場合、Hibernateはいくつかのエラーに不満を言います。 update = "false"を定義し、entityBプロパティに挿入= "false"を定義する理由を説明します。
よろしく、
他のヒント
冬眠hbm.xmlファイルで、いつでも外部キーDDLを手動で作成できます。
<hibernate-mapping>
...
<database-object>
<create>[CREATE FK]</create>
<drop>[DROP FK]</drop>
</database-object>
</hibernate-mapping>
また、さまざまな方言をサポートする必要がある場合は、これを範囲することもできます。
チェックアウト 5.7。補助データベースオブジェクト
あなたが取ることができるもう1つのアプローチは、Aマッピングではなく、BマッピングでFKを定義することです。 JPAコードを追加しました。注釈を使用していない場合は、これをHibernateマッピングファイルに翻訳する必要があります。
@Entity
public class B
{
private long id;
private List<A> aList;
@Id
@Column( name = "ID" )
public long getId()
{
return id;
}
@OneToMany
@JoinColumn( name = "B_ID" )
public List<A> getAList()
{
return aList;
}
public void setId( long id )
{
this.id = id;
}
public void setAList( List<A> aList )
{
this.aList = aList;
}
}
A.Javaは次のようになりません:
@Entity
public class A
{
private long id;
private long idOfB;
@Id
@Column( name = "ID" )
public long getId()
{
return id;
}
@Column( name = "B_ID" )
public long getIdOfB()
{
return idOfB;
}
public void setId( long id )
{
this.id = id;
}
public void setIdOfB( long idOfB )
{
this.idOfB = idOfB;
}
}
オブジェクトをオブジェクトに関連付けて、冬眠の完全な利点を得ることをお勧めします。問題はあなたが得る例外だと思います。これは、怠zyなオブジェクトを取得しようとすると、冬眠セッションが既に閉じられているためです。このブログには、この問題への回答を示すいくつかの投稿があります。たとえば、これは次のとおりです。テキストをリンクします.
Springを使用している場合は、OpenEntityManagerInviewFilterを使用して、ビューがレンダリングになるまでセッションを開き続けることができます。