[英]Hibernate Criteria API - Filtering collection property
我有这样的实体:
@Entity
public class Album {
private Integer id;
private Integer ownerId;
private String name;
private String description;
private Date created;
@OneToMany @JoinColumn(name = "albumId")
private Set<AlbumUser> users = new HashSet<AlbumUser>();
@OneToMany @JoinColumn(name = "albumId")
private Set<Picture> pictures = new HashSet<Picture>();
}
还有一个:
@Entity
public class Picture {
private Integer id;
private Integer creatorId;
private Integer albumId;
private Date created;
private String title;
private String description;
@ManyToOne @JoinColumn(name = "eventId")
private Event event;
}
使用标准 API 我想获得带有过滤图片集的唯一 AlbumD。 我尝试这样的事情:
public Album read(Integer albumId, Set<Integer> picFilter) {
Criteria crit = getCurrentSession().createCriteria(Album.class, "album");
crit.add(Restrictions.idEq(albumId));
if (picFilter != null && !picFilter.isEmpty()) {
crit = crit.createAlias("album.pictures", "picture");
crit.add(Restrictions.in("picture.event.id", picFilter));
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
Album resultDs = (Album) crit.uniqueResult();
return resultDs;
}
在这里,我得到了所有相关图片的专辑。 它们根本没有被过滤。 当我尝试执行记录器打印的查询时,我只得到四行,即具有给定 eventId 的图片数量,但在相册中我得到所有图片。
我也尝试了其他 ResultTransformers,但最终得到了很多结果(4),结果并不明显。
我错过了什么或做错了什么?
您无法通过在查询中包含对集合的限制来过滤与实体关联的 Collections 的内容。 该查询将仅获取专辑。 可以在以后访问 Collection 时获取 Collection 的内容。 您所做的只是过滤相册以仅检索那些包含带有事件 ID 的图片的相册。
如果集合仅包含与您的条件匹配的图片并且您将获得部分集合,则会导致更新问题,因为 Hibernate 然后认为过滤的项目已被删除,并会更新数据库以反映该更改,实际上删除了这些项目从收藏。
如果您只想从集合中接收一些项目,您可以使用Session.createFilter()方法。 唯一的问题是,它目前只支持 HQL 查询。
我记得这是我最近做的事情的一个问题。 你有没有试过这个:
if (picFilter != null && !picFilter.isEmpty()) {
Criteria subCriteria = crit.createCriteria("album.pictures"); // Or just 'pictures?'
Disjunction or = Restrictions.disjunction();
for (Integer id : picFilter)
or.add(Restrictions.idEq(id));
subCriteria.add(or);
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
如果将别名与 left_join 一起使用,它将仅返回满足相关条件的子 object。 否则,它返回满足条件但设置了所有子 object 的主 object。
crit = crit.createAlias("album.pictures", "picture", CriteriaSpecification.LEFT_JOIN);
此方法在某些 hibernate 版本中已弃用,如果是这样,您也可以使用以下解决方案: 过滤复杂集的标准
尝试这个:
Criteria crit = getCurrentSession().createCriteria(Album.class, "album");
crit.add(Restrictions.idEq(albumId));
if (picFilter != null && !picFilter.isEmpty()) {
crit.createAlias("album.pictures", "picture");
crit.createAlias("picture.event", "event");
crit.add(Restrictions.in("event.id", picFilter));
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.