简体   繁体   English

Hibernate 标准 API - 过滤集合属性

[英]Hibernate Criteria API - Filtering collection property

I have such entity:我有这样的实体:

@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>();
}

and another one:还有一个:

@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;
}

Using Criteria API I want to get unique AlbumDs with filtered set of Picturs.使用标准 API 我想获得带有过滤图片集的唯一 AlbumD。 I try something like this:我尝试这样的事情:

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;
}

And here I get Album with all pictures associated.在这里,我得到了所有相关图片的专辑。 They're not filtered at all.它们根本没有被过滤。 When I try to execute query printed by a logger, I get only four rows wich is the number of pictures with given eventId, but in the Album I get all pictures.当我尝试执行记录器打印的查询时,我只得到四行,即具有给定 eventId 的图片数量,但在相册中我得到所有图片。

I also tried other ResultTransformers, but eventualy got many result (4) not distinct one.我也尝试了其他 ResultTransformers,但最终得到了很多结果(4),结果并不明显。

What do I miss or do wrong?我错过了什么或做错了什么?

You can not filter the content of Collections associated with an entity by including Restrictions on the Collection in the query.您无法通过在查询中包含对集合的限制来过滤与实体关联的 Collections 的内容。 The query will only fetch the Albums.该查询将仅获取专辑。 The content of the Collection can be fetched later, when the Collection is accessed.可以在以后访问 Collection 时获取 Collection 的内容。 All you do is filter the Albums to retrieve only those Albums that contain the Pictures with the event ids.您所做的只是过滤相册以仅检索那些包含带有事件 ID 的图片的相册。

If the Collection would only contain the Pictures that match your Criteria and you would get a partial Collection it would cause problems on updates, because Hibernate then think the filtered items have been removed and would update the database to reflect that change, actually removing the items from the Collection.如果集合仅包含与您的条件匹配的图片并且您将获得部分集合,则会导致更新问题,因为 Hibernate 然后认为过滤的项目已被删除,并会更新数据库以反映该更改,实际上删除了这些项目从收藏。

If you want to receive only some items from a Collection you can use the Session.createFilter() method.如果您只想从集合中接收一些项目,您可以使用Session.createFilter()方法。 The only problem is, that it only supports HQL queries currently.唯一的问题是,它目前只支持 HQL 查询。

I recall this being an issue for something I did recently.我记得这是我最近做的事情的一个问题。 Have you tried this:你有没有试过这个:

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); 
 }

If you use alias with left_join, it will return just sub object which satisfy related condition.如果将别名与 left_join 一起使用,它将仅返回满足相关条件的子 object。 Otherwise it returns main object which satisfy conditions but with all of sub object set.否则,它返回满足条件但设置了所有子 object 的主 object。

crit = crit.createAlias("album.pictures", "picture", CriteriaSpecification.LEFT_JOIN);

This method is deprrecated in some hibernate version, if so you can use below solution for it too: criteria with filtered complex set此方法在某些 hibernate 版本中已弃用,如果是这样,您也可以使用以下解决方案: 过滤复杂集的标准

try this:尝试这个:

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM