【发布时间】:2017-12-05 15:07:20
【问题描述】:
我有以下实体,item 最多可以有两个类别,主要和次要。
这两个类别都使用JoinColumnsOrFormulas 映射到ManyToOne 到category 表。
第一个按预期获取EAGER,但第二个不会出现在 SQL 语句中并被延迟加载。
这种延迟加载会导致经典的 n+1 问题。
这是我的项目实体,两个类别实体都应该加入:
@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.Final。
这是基本实体的样子:
@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();
}
}
这是一个“查询”示例,正如我所说我使用的是休眠条件以及 HQL,这两种方法都会出现问题。
session
.createCriteria(Item.class)
.add(eq("id", id))
.uniqueResult();
【问题讨论】:
-
尝试使用标准 jpa @JoinColumns.. 而不是休眠的
-
数据库模型中的任何细节?例如,我第二类可以为空?
-
如何加载
Items? -
如何查询您的
Items?只是"from Item",还是涉及更多内容?另外,请提供您的StackOverflowQuestionEntity的来源,如果您有任何确定的内容,可以添加您对使用 JPA 注释的研究结果 -
@GuidoKrömer 你用来获取的代码是什么,你能把它包括进来吗?我认为这一切都不同
标签: java postgresql hibernate many-to-one eager