11

多対 1 要素で宣言されているドメイン オブジェクトにプロパティがあります。このプロパティの基本的な構文は次のようになります。

<many-to-one name="propertyName" class="propertyClass" fetch="select" not-found="ignore" lazy="proxy" />

ここでのアイデアは、Hibernate がこのプロパティを積極的にフェッチしないようにすることです。null の可能性があるため、not-found 無視が設定されます。

しかし、Hibernate は、この関連付けを含むクラスをロードすると、親クラスがロードされるときに実際のクラス (プロキシでさえない) インスタンスをロードします。一部のプロパティはサイズが 1MB を超えるため、大量のヒープ スペースを占有します。

ただし、not-found が例外に設定されている (またはデフォルトで例外に設定されている) 場合、このプロパティを持つ親クラスはプロキシをロードします!

このプロパティをnullにすることを許可しながら、休止状態がプロキシをロードしないようにするにはどうすればよいですか?

私は lazy=no-proxy を見つけましたが、ドキュメンテーションはある種のバイトコードの変更について述べており、詳細には触れていません。誰かが私を助けることができますか?

問題があれば、それは Hibernate の Java バージョンであり、少なくともバージョン 3 です (役立つ場合は実際のバージョンを調べることができますが、今のところ Hibernate 3+ です)。

先に明記しませんでしたが、Java のバージョンは 1.4 です。そのため、Java アノテーションはサポートされていません。

4

6 に答える 6

9

アソシエーションのもう一方の端がnullになる可能性がある場合、プロキシを使用する必要があるかどうかを判断するために、hibernate はアソシエーションの端を照会する必要があると思います (もう一方の端がnullの場合、プロキシは必要ありません)。参考文献は今のところ見つけられませんが、どこかで読んだ記憶があります。

フィールドの遅延読み込みを提供するために、ドキュメントではビルド時のフィールドのバイトコード拡張について言及しています: Using lazy property fetching 。ここに抜粋があります:

Hibernate3 は、個々のプロパティの遅延フェッチをサポートしています。この最適化手法は、フェッチ グループとも呼ばれます。実際には、行の読み取りを最適化することは、列の読み取りを最適化することよりもはるかに重要であるため、これは主にマーケティング機能であることに注意してください。ただし、レガシー テーブルに数百の列があり、データ モデルを改善できない場合など、極端な場合には、クラスの一部のプロパティのみを読み込むことが役立つ場合があります。

プロパティの遅延読み込みには、ビルド時のバイトコード インストルメンテーションが必要です。永続クラスが強化されていない場合、Hibernate は遅延プロパティ設定を黙って無視し、即時フェッチにフォールバックします。

于 2008-10-21T16:50:44.867 に答える
2

私は lazy=no-proxy を見つけましたが、ドキュメンテーションはある種のバイトコードの変更について述べており、詳細には触れていません。誰かが私を助けることができますか?

プロジェクトのビルドに ANT を使用していると仮定します。

<property name="src" value="/your/src/directory"/><!-- path of the source files -->
<property name="libs" value="/your/libs/directory"/><!-- path of your libraries -->
<property name="destination" value="/your/build/directory"/><!-- path of your build directory -->

<fileset id="applibs" dir="${libs}">
  <include name="hibernate3.jar" />
  <!-- include any other libraries you'll need here -->
</fileset>

<target name="compile">
  <javac srcdir="${src}" destdir="${destination}" debug="yes">
    <classpath>
      <fileset refid="applibs"/>
    </classpath>
  </javac>
</target>

<target name="instrument" depends="compile">
  <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
    <classpath>
      <fileset refid="applibs"/>
    </classpath>
  </taskdef>

  <instrument verbose="true">
    <fileset dir="${destination}">
      <!-- substitute the package where you keep your domain objs -->
      <include name="/com/mycompany/domainobjects/*.class"/>
    </fileset>
  </instrument>
</target>
于 2009-08-22T00:23:44.663 に答える
2

クラスが最終版でないことを確認してください。

于 2011-02-23T16:16:47.347 に答える
0

@Miguel Ping:あなたが参照しているページは[ http://www.hibernate.org/162.html]だと思います。私が理解している限り、外部キーが存在しない1対1の場合は、追加のSELECTが必要です。設定constrained="true"により、Hibernateに、反対側が常に存在し、追加のSELECTは不要であることを通知します。

したがって、外部キーが存在する多対1側の場合、FKの値によってもう一方の端が存在するかどうかがわかるため、別のSELECTを実行する必要はありませんnull。少なくとも、これは私がそれを理解する方法です。

これまでのところ、理論については。プロキシは、外部キー/多対1側で機能します。アソシエーションに使用されるマッピングは次のとおりです。

<many-to-one name="haendler" column="VERK_HAENDLOID" lazy="proxy" />

ただし、指定されたURL()で説明されているようなマッピングを使用した場合、プロキシは1対1では機能しませんconstrained="true"。うーん、これについて質問を開くと思います。;-)

于 2009-05-08T07:49:51.017 に答える
0

コントローラーを介してモデルからビューに hibernate オブジェクトを渡す場合は、そうしないでください。

代わりに、ビューに渡して表示する Hibernate オブジェクトの値を格納する「スナップショット オブジェクト」を作成します。

なんで? プロキシはコントローラーにある場合でも値を取得できます...ただし、プロキシ/オブジェクトをビューに渡すと、トランザクションが既に終了しているため、値を取得できなくなります。そして、これが私が上記のものを提案した理由です。

于 2008-10-21T16:17:21.423 に答える
0

Hibernate アノテーションを使用する場合、関連付けに @ManyToOne(fetch = FetchType.LAZY) を配置すると、目的が達成されます。fetch="lazy" を設定して、それが機能するかどうかを確認しましたか?

于 2008-10-21T18:36:05.277 に答える