私は、次のエンティティ(のみ関係マッピングが示す)持っている:JPA/Hibernate:@ManyToOneと@OneToOneの関係はFetchType.LAZYとタグ付けされ、オプション= falseはem.find()に遅れてロードされませんか?
@Entity
@Table(name = "PQs")
public class PQ implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer id;
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY) // lazy XToOne
@JoinColumn(name = "user_id", referencedColumnName = "person_id")
private User user;
@OneToOne(mappedBy = "pq", fetch = FetchType.LAZY) // lazy XToOne
private Group group;
@OneToOne(mappedBy = "pq", fetch = FetchType.LAZY) // lazy XToOne
private Tendering tendering;
...
}
注上記のコメントを:
ユーザー(でSecurityIdentityサブクラスシンプルで:他のエンティティへの3人の@XToOne
関係があります所有者)を表すPQによって参照PKとしてID:
@Entity
@Table(name = "Users")
@DiscriminatorValue(value = "user")
public class User extends SecurityIdentity
{
@Column
private String name;
@OneToMany(mappedBy = "user")
private Set<PQ> pqs = new HashSet<PQ>();
...
}
グループを(A PKのような単純なIDを持つでSecurityIdentityサブクラスLSO、)そのPQと対話することができ、ユーザーの集合を表すためにPQを参照:を入札
@Entity
@Table(name = "Groups")
@DiscriminatorValue(value = "group")
public class Group extends SecurityIdentity
{
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pq_id", referencedColumnName = "id")
private PQ pq;
...
}
:
@Entity
@Table(name = "Tenderings")
public class Tendering implements Serializable
{
@Id
@Column(name = "pq_id", insertable = false, updatable = false)
private Integer pqId;
@Column(name = "external_code")
private String externalCode;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pq_id", referencedColumnName = "id")
private PQ pq;
...
}
しないでくださいグループとユーザーがIDを共有するのを混乱させて、単純なIDとして扱うだけです。入札は単なる別のドキュメントオブジェクト(一対一)です。
PQエンティティには3つの@XToOne
リレーションシップがあります。フェッチタイプが設定されていない場合は、熱心に読み込まれます(JPAデフォルト)。だから私はこれを防ぐために@XToOne
の関係をFetchType.LAZY
とタグ付けしました。今
em.find(PQ.class, someExistingId);
を使用して、私はHibernateの出力が得られます(ネット上の多くの場所で説明したように)
23:53:55,815 INFO [stdout] Hibernate: select pq0_.id as id291_0_, pq0_.description as descript2_291_0_, pq0_.name as name291_0_, pq0_.submission_date as submission4_291_0_, pq0_.user_id as user5_291_0_ from PQs pq0_ where pq0_.id=?
23:53:55,818 INFO [stdout] Hibernate: select user0_.id as id280_0_, user0_1_.identity_type_id as identity2_280_0_, user0_.is_enabled as is1_297_0_, user0_.name as name297_0_, user0_.password as password297_0_, user0_.person_id as person5_297_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
23:53:55,821 INFO [stdout] Hibernate: select group0_.id as id280_0_, group0_1_.identity_type_id as identity2_280_0_, group0_.pq_id as pq2_281_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
23:53:55,823 INFO [stdout] Hibernate: select tendering0_.pq_id as pq1_296_0_, tendering0_.binary_file as binary2_296_0_, tendering0_.customer_id as customer6_296_0_, tendering0_.description as descript3_296_0_, tendering0_.external_code as external4_296_0_, tendering0_.title as title296_0_ from Tenderings tendering0_ where tendering0_.pq_id=?
3つの余分のSELECTは@XToOne関係から生じます。私はほとんど見ていたソースはこれです:そこに述べたように
Making a OneToOne-relation lazy
、@ManyToOne
関係User user
がフェッチすべきではない:
@ManyToOne(fetch=FetchType.LAZY)
はうまく動作するはずです。あなたはselect user0_.id as id280_0_, ...
の文から見ることができるよう
が...ここPQユーザーへの関係が、それは、他の2つのGroup group
とTendering tendering
については
...フェッチされ、両方とも@OneToOne
逆マッピングの場合、外部キーはPQエンティティで同じマッピングをもたらすPQテーブルのPK(ID)を参照します。
3つの関係はすべてオプションではないことに注意してください.PQは常に所有者(ユーザー)を持ち、PQは常に入札およびグループエンティティによって参照されます。私はちょうど上記のJPAでそれをモデル化していなかった...
PQエンティティの3つの関係にoptional = false
を追加するときに、:
@Entity
@Table(name = "PQs")
public class PQ implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer id;
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", referencedColumnName = "person_id")
private User user;
@OneToOne(mappedBy = "pq", fetch = FetchType.LAZY, optional = false)
private Group group;
@OneToOne(mappedBy = "pq", fetch = FetchType.LAZY, optional = false)
private Tendering tendering;
...
}
...私は、次のHibernateの出力を得る:私はしてきたことを
00:47:34,397 INFO [stdout] Hibernate: select pq0_.id as id361_0_, pq0_.description as descript2_361_0_, pq0_.name as name361_0_, pq0_.submission_date as submission4_361_0_, pq0_.user_id as user5_361_0_ from PQs pq0_ where pq0_.id=?
00:47:34,410 INFO [stdout] Hibernate: select user0_.id as id350_0_, user0_1_.identity_type_id as identity2_350_0_, user0_.is_enabled as is1_367_0_, user0_.name as name367_0_, user0_.password as password367_0_, user0_.person_id as person5_367_0_ from Users user0_ inner join SecurityIdentities user0_1_ on user0_.id=user0_1_.id where user0_.person_id=?
00:47:34,413 INFO [stdout] Hibernate: select group0_.id as id350_0_, group0_1_.identity_type_id as identity2_350_0_, group0_.pq_id as pq2_351_0_ from Groups group0_ inner join SecurityIdentities group0_1_ on group0_.id=group0_1_.id where group0_.pq_id=?
注意、これはem.find(...)
で使用しているので、PQエンティティのoptional = false
で再生しています。 (これが十分でない場合は、私を啓発してください。)
私の質問は今二つある:
User
エンティティへ@ManyToOne
ですがいい加減に仕事ができると言われたことを考えると(熱心にフェッチされるのはなぜ、Making a OneToOne-relation lazyを参照)?- はなぜ
Tendering
エンティティにのみOneToOne
関係がフェッチされてオフ残っていますか?それはTendering
エンティティがGroup
実体がないPK自体(Tendering
で@Id
)としてPQのPK列、(PQのPKへの定期的な関係)を参照しているためですか?
は何が悪いのでしょうか?これらの非オプションの関係を怠惰にするにはどうすればよいですか?
私は、LAZYのことは、JPAプロバイダがレイジーローディングについて何かをするためのヒントであることは知っていますが、この場合はまるでそうであるように見えます他の何かが間違っている(その一部が機能している)。
PS:私はJBoss 7.0.0.Finalに付属しているバージョンで、JPAアノテーションのみでHibernate 4.0 BETAを使用しています(上記はすべてJPA 1.0と互換性があります)。
これは単なるバグです。 https:// hibernateを参照してください。onjira.com/browse/HHH-3930、それは似ています。 –