6

次のマッピングが提供されていると仮定します。

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

起動時にHibernateによって外部キーが引き続き適用および作成されるように、Hibernateマッピングを変更することは可能ですか?ただし、クラス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()したいと思います。long idOfBこれにより、オブジェクトの読み込みもA速くなります。

私の質問はこれa.getB().getId()と非常に似ていると思いますが、提供された解決策(遅延読み込みを使用する)は私の場合は適切ではありLazyInitializationExceptionませa.getIdOfB()ん。

よろしくお願いします。

4

4 に答える 4

12

言われるように

<many-to-one...を<property...に変換すると、これは機能しますが、データベースによって外部キーが強制されないことを理解しています。

だから私のアドバイスは:両方を使う

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はいくつかのエラーを訴えます。これは、entityBプロパティでupdate="false"とinsert="false"を定義する理由を説明しています。

よろしく、

于 2010-01-26T03:09:22.090 に答える
4

休止状態のhbm.xmlファイルに外部キーDDLを手動でいつでも作成できます。

<hibernate-mapping>
    ...
    <database-object>
        <create>[CREATE FK]</create>
        <drop>[DROP FK]</drop>
    </database-object> 
</hibernate-mapping>

異なる方言をサポートする必要がある場合は、これをスコープすることもできます。

5.7をチェックしてください。補助データベースオブジェクト

于 2010-01-25T17:57:36.353 に答える
0

採用できるもう1つのアプローチは、AマッピングではなくBマッピングを使用してFKを定義することです。JPAコードを追加しました。注釈を使用していない場合は、これを休止状態のマッピングファイルに変換する必要があります。

@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;
    }   
}
于 2010-01-25T18:14:52.510 に答える
0

Hibernateの利点を最大限に活用するには、オブジェクトをオブジェクトに関連付けることをお勧めします。問題はあなたが得る例外だと思います。これは、レイジーオブジェクトを取得しようとしたときに、Hibernateセッションがすでに閉じられているためです。このブログには、この問題への回答を示すいくつかの投稿があります。たとえば、リンクテキストです。

Springを使用している場合は、OpenEntityManagerInViewFilterを使用して、ビューがレンダリングされるまでセッションが開いたままになるようにすることができます。

于 2010-01-25T20:05:16.813 に答える