Я создал список документов с тегами, со многими отношениями между тегами и документами. Теперь я хотел бы использовать механизм критериев спящего режима для запроса «сводки» каждого тега, который включает в себя подсчет того, как часто использовался конкретный тег, с дополнительным ограничением на то, был ли опубликован этот документ.Ограничение соединения слева от гибернации в отношениях «многие ко многим»
Субъектами Я использую примерно выглядеть следующим образом (Вы заметите 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
Как вы можете видеть выше, ограничение публикации применяется к обоим левым внешним соединениям. Я не уверен, что это по дизайну, однако мне нужно, чтобы опубликованное ограничение применялось ТОЛЬКО ко второму левому внешнему соединению.
Любые идеи?