簡體   English   中英

Hibernate 標准 API - 過濾集合屬性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM