次のエンティティを持っています。item
には、プライマリとセカンダリの2つのカテゴリがあります。 両方のカテゴリはJoinColumnsOrFormulas
を使用してをcategory
テーブルにマッピングします。 最初のものは期待どおりにEAGER
をフェッチしますが、2番目のものはSQL文では発生せず、遅延ロードされます。 この遅延読み込みは、古典的なn + 1問題を引き起こします。1つのテーブルで2つのManyToOneリレーションをHibernateし、最初にEagerを取得し、2番目のLAZYをロードします
これは、参加しますする必要があり、両方のカテゴリのエンティティと私のアイテムの実体である:
@Entity
@Table(name = "item", schema = "public", catalog = "stackoverflow_question")
@DynamicUpdate
public class Item extends StackOverflowQuestionEntity {
@Id
@Column(name = "id")
protected Long id;
@Column(name = "site")
private String site;
@ManyToOne
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(value = "site", referencedColumnName = "site")),
@JoinColumnOrFormula(formula = @JoinFormula(value = "primary_category_id", referencedColumnName = "category_id"))
})
private Category primaryCategory;
@Column(name = "primary_category_id")
private Long primaryCategoryId;
@ManyToOne
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(value = "site", referencedColumnName = "site")),
@JoinColumnOrFormula(formula = @JoinFormula(value = "secondary_category_id", referencedColumnName = "category_id"))
})
private Category secondaryCategory;
@Column(name = "secondary_category_id")
private Long secondaryCategoryId;
}
これはカテゴリのエンティティである:
@Entity
@Table(name = "category", schema = "public", catalog = "stackoverflow_question")
public class Category extends StackOverflowQuestionEntity {
@Column(name = "category_id")
private Long categoryId;
@Column(name = "name")
private String name;
@Column(name = "site")
private String site;
}
結果のクエリのみ主要なカテゴリが含まれます。
をSELECT this_.id AS id1_9_9_,
this_.inserted AS inserted2_9_9_,
this_.updated AS updated3_9_9_,
this_.primary_category_id AS formula174_9_,
this_.secondary_category_id AS formula176_9_,
category2_.id AS id1_0_0_,
category2_.inserted AS inserted2_0_0_,
category2_.updated AS updated3_0_0_,
category2_.name AS name7_0_0_
FROM public.item this_
LEFT OUTER JOIN public.category category2_ ON this_.site=category2_.site
AND this_.primary_category_id=category2_.category_id
WHERE True;
したがって、セカンダリカテゴリは遅延接続されます。
SELECT category0_.id AS id1_0_0_,
category0_.inserted AS inserted2_0_0_,
category0_.updated AS updated3_0_0_,
category0_.name AS name4_0_0_,
category0_.site AS site5_0_0_
FROM public.category category0_
WHERE category0_.site=?
AND category0_.category_id=?;
なぜ、Hibernateがセカンダリカテゴリに怠惰に加わったのか、そのアノテーションは同じように見えます。
私が使用している休止状態のバージョンは5.0.10.最終です。
これは基本エンティティがどのように見えるかです:私はHibernateの基準だけでなく、HQLを使用しています、問題は両方の方法で発生言ったようにここで
@MappedSuperclass
abstract public class StackOverflowQuestionEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, insertable = true, updatable = false, nullable = false)
protected Long id;
@Type(type="LocalDateTime")
@Column(name = "created", nullable = false, insertable = true, updatable = false)
protected LocalDateTime created;
@Type(type="LocalDateTime")
@Column(name = "refreshed", nullable = false, insertable = true, updatable = true)
protected LocalDateTime refreshed;
@PreUpdate
protected void onUpdate() {
refreshed = now();
}
@PrePersist
protected void onCreate() {
created = refreshed = now();
}
}
は、「クエリ」の例です。 (を更新)それは次のようになり、標準のJPAの注釈付き
session
.createCriteria(Item.class)
.add(eq("id", id))
.uniqueResult();
同じSELECTで接合されている代わりに、データベースモデルに1つの –
どれ詳細を休止状態の...標準のJPA @JoinColumnsを使用しようか?私は2番目のカテゴリはnullable例えば? – Gimby
両方のカテゴリIDは、データベースモデルでNULL可能です。 \ dアイテム primary_category_id | bigint secondary_category_id | bigint –