非常に単純な選択 (SELECT h FROM Hero h where h.owner = :player) が n+1 問題を引き起こすという問題があります。クエリは、各ヒーロー エンティティのゲームへの選択をトリガーします。
最初に、選択中に代替クエリを削除するフェッチ タイプ レイジーを追加しました。私のコードでは、IDを取得するためにゲームが1回だけ必要です。これにより、すべてのエンティティに対して再度選択がトリガーされました。
だから私は助けになった結合フェッチを追加しましたが、それは私が必要としない結合を引き起こします! エンティティ全体をフェッチせずに、休止状態のプロキシ オブジェクトに ID を渡すように指示するにはどうすればよいですか?
そこでのヒントを試してみましたが成功しませんでした: http://256stuff.com/gray/docs/misc/hibernate_lazy_field_access_annotations.shtml
hibernate の @AccessType と javax の @Access はどちらも違いはありません。getId() を呼び出すと、ゲームは常に取得されます。
私が見逃しているアイデアはありますか? 私はこれをかなり頻繁に必要とするので、できれば結合を避けたいと思っています。
挨拶、マルクス
PS: jboss 7 で jpa2 + hibernate 4 を使用しています。
@Entity
@NamedQueries({
@NamedQuery(name = "Hero.findByPlayer", query = "SELECT h FROM Hero h JOIN FETCH h.game where h.owner = :player")
})
public class Hero extends GameCharacter implements Serializable {
@ManyToOne
private Player owner;
@Entity
public abstract class GameCharacter extends GameObject implements Serializable {
... nothing special in here
}
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class GameObject implements Serializable {
@Id
private String id = java.util.UUID.randomUUID().toString();
@ManyToOne(fetch=FetchType.LAZY)
protected Game game;
@Entity
public class Game implements Serializable {
private static final long serialVersionUID = 4379242677193301727L;
@Id
private String id = java.util.UUID.randomUUID().toString();