6

私は本当に厄介な状況に出くわしました: 私はアプリのバックエンドとして Hibernate & Spring を使用していますが、場合によっては、特定のエンティティとの関係にあるエンティティが DB から通常のエンティティ オブジェクトとしてフェッチされていないようです。ただし、Javassist タイプとして。例えば:

次の関係を持つ Campaign エンティティがあります。

@Entity
@Table(name = "campaign")
public class Campaign implements Serializable {
  [..]
  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {
        "campaign_id", "dealer_id" }), name = "campaign_has_dealer", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "dealer_id", nullable = false) })
  private List<Dealer> dealers = new ArrayList<Dealer>();

@ManyToMany
// (fetch = FetchType.LAZY)
@JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {
        "campaign_id", "sales_area_id" }), name = "campaign_has_sales_area", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "sales_area_id", nullable = false) })
private List<SalesArea> salesAreas = new ArrayList<SalesArea>();
}

このキャンペーンに接続された salesAreas を取得すると、SalesArea_$$_javassist_56 のリストが取得され、ディーラーの場合は通常の Hibernate エンティティが取得されます。クライアント部分は GWT に基づいているため、ものを取得するために RequestFactory を使用します。最初はプロキシやロケーターなどに問題があると思っていましたが、これらが取得されるサービスにブレークポイントを設定し、それらを選択するとすぐに Javassist オブジェクトになります。FetchType.LAZY アノテーションを削除しても (望ましい解決策ではありませんが)、同じことが起こるようです。これは、@ManyToMany だけでなく、他のタイプの関係でも発生しました。

アノテーションには GWT 2.3、Spring 3、Hibernate 3.6.3、および JPA 2.0 を使用しています。

任意の提案をいただければ幸いです。

前もって感謝します

4

3 に答える 3

4

私が見る限り、あなたが抱えている大きな問題は、関連付けのフェッチ タイプではなく、プロキシされたタイプが RequestFactory でうまく機能しないことです。

はい、フェッチ戦略を変更することで解決できますが、奇妙な状況で壊れる可能性のある弱い回避策のように思えます。

それを解決する方法を正確に覚えていませんが、解決しました。覚えている限り、ServiceLayerDecorator クラスに拡張ポイントがありました。基本的に、返されるオブジェクトが Hibernate プロキシであるかどうかを確認し (Hibernate クラスと HibernateProxy クラスを確認します)、代わりに ServiceLayerDecorator で非プロキシ タイプを返します。( http://code.google.com/p/google-web-toolkit/issues/detail?id=6767 )

フェッチ戦略に関しては、N が大きい (おそらく 1000) @BatchSize(N) をお勧めしますが、これは独立したテーマです。

幸運を!

于 2011-12-08T05:25:23.523 に答える
0

HibernateのプロキシモデルとJavassistを使用して、低速の従来のHibernateランタイムリフレクション操作を回避することで、JDO実装(DataNucleusなど)のような完全なバイトコード拡張ソリューションを使用するクリーンで直感的なエクスペリエンスほどエレガントになることはありません。 。

個人的には、非常に多くの問題を引き起こし、奇妙で直感的でない回避策を必要とする壊れたコードについての質問でWebを埋める解決策を維持する(駄洒落を許す)意味を理解することはできませんが、それでも人々はそうします...

ただし、質問に戻ります。JPAを使用している場合、問題の1つの解決策は、DataNucleus/JDOの多くの利点をもたらすDataNucleus/JPAを使用することです(クリーンな基盤となる実装-プロキシやJavassistクラスなどはありません。 )JPA準拠の実装の場合-つまり、使用を開始するために既存のソースコードを変更する必要はありません。

于 2012-10-11T07:02:34.717 に答える