[英]Hibernate left join constraint in a many-to-many relationship
我建立了一个可标记文档列表,标签和文档之间具有多对多关系。 我现在想使用休眠标准机制来查询每个标签的“摘要”,其中包括对使用特定标签的频率的计数,并对是否已发布文档有一个额外的限制。
我正在使用的实体大致如下所示(您会在中间注意到一个SQL连接表):
@Entity
public class DocumentTag {
... various things ...
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "tags")
private List<Document> documents = new ArrayList<>();
}
@Entity
public class Document {
... various things ...
@Basic
@Column(name = "published", columnDefinition = "BIT", length = 1)
protected boolean published = false;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "document_tag_joins",
uniqueConstraints = @UniqueConstraint(
columnNames = {"document", "tag"}
),
joinColumns = {@JoinColumn(name = "document")},
inverseJoinColumns = {@JoinColumn(name = "tag")})
private List<DocumentTag> tags = new ArrayList<>();
}
鉴于以上所述,我设法弄清楚了构建查询应该或多或少地如下工作:
Criteria c = session.createCriteria(DocumentTag.class);
c.createAlias("documents", "docs",
JoinType.LEFT_OUTER_JOIN,
Restrictions.eq("published", true)
);
c.setProjection(
Projections.projectionList()
.add(Projections.alias(Projections.groupProperty("id"), "id"))
.add(Projections.alias(Projections.property("createdDate"), "createdDate"))
.add(Projections.alias(Projections.property("modifiedDate"), "modifiedDate"))
.add(Projections.alias(Projections.property("name"), "name"))
.add(Projections.countDistinct("docs.id"), "documentCount"));
// Custom response entity mapping
c.setResultTransformer(
Transformers.aliasToBean(DocumentTagSummary.class)
);
List<DocumentTagSummary> results = c.list();
鉴于以上所述,休眠生成的SQL查询如下所示:
SELECT
this_.id AS y0_,
this_.createdDate AS y1_,
this_.modifiedDate AS y2_,
this_.name AS y3_,
count(DISTINCT doc1_.id) AS y5_
FROM tags this_
LEFT OUTER JOIN tag_joins documents3_
ON this_.id = documents3_.tag AND (doc1_.published = ?)
LEFT OUTER JOIN documents doc1_
ON documents3_.document = doc1_.id AND (doc1_.published = ?)
GROUP BY this_.id
如上所示,发布约束同时应用于两个左外部联接。 我不确定这是否是设计使然,但是我需要的是将发布的约束仅应用于第二个左外部联接。
有任何想法吗?
我可以通过横向解决这个问题。 首先,我必须将“已发布”列更改为使用整数而不是一点。 然后,我可以对结果的投影进行如下修改:
// Start building the projections
ProjectionList projections =
Projections.projectionList()
.add(Projections.alias(
Projections.groupProperty("id"), "id"))
.add(Projections.alias(
Projections.property("createdDate"),
"createdDate"))
.add(Projections.alias(
Projections.property("modifiedDate"),
"modifiedDate"))
.add(Projections.alias(
Projections.property("name"), "name"));
if (isAdmin()) {
// Give the raw count.
projections.add(Projections.countDistinct("docs.id"), "documentCount");
} else {
// Use the sum of the "published" field.
projections.add(Projections.sum("docs.published"), "documentCount");
}
我承认这并没有真正回答关于为什么多对多表上的休眠条件约束适用于所有表的问题,但这解决了我的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.