2014-06-05 51 views
0

我的應用程序的一個組件記錄用戶使用http URL發送的參數。映射情況如下:Hibernate Criteria條件或OneToMany屬性值的子查詢

public class ActivityLog { 

    @Column(name = "id") 
    private Long id; 

    @OneToMany(mappedBy="activityLog", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    protected List<ActivityLogParameter> activityLogParameters = new ArrayList<ActivityLogParameter>(); 
} 

public class ActivityLogParameter { 

    @Column(name = "id") 
    private Long id; 

    @Column(name = "key", length=10) 
    protected String key; 

    @Column(name = "value", length=50) 
    protected String value; 

    @ManyToOne(fetch = FetchType.LAZY, cascade={CascadeType.MERGE}) 
    @JoinColumn(name="activity_log_id") 
    protected ActivityLog activityLog; 
} 

讓每URL總是2級的參數被傳遞假設:U和L

我需要使用Hibernate的標準(從規範強制性),以便它返回到創建一個查詢我所有的ActivityLogs都有一個特定的值。即:U = AAA和L = BBB

我想是這樣的:

Criteria criteria = getCurrentSession().createCriteria(ActivityLog.class, "al"); 
// create alias 
criteria = criteria.createAlias("activityLogParameters", "alp",JoinFragment.LEFT_OUTER_JOIN); 

// create transformer to avoid duplicate results 
criteria = criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 
criteria = criteria.setFetchMode("al.activityLogParameters", FetchMode.SELECT); 

//filters 
criteria = criteria.add(Restrictions.or(Restrictions.eq("alp.value", UValue), Restrictions.ne("alp.key", "L"))); 
criteria = criteria.add(Restrictions.or(Restrictions.eq("alp.value", LValue), Restrictions.ne("alp.key", "U"))); 

但在這裏我卡住了。我試圖在這方面添加像獨特和分組這樣的投影,但僅僅得到正確的結果是不夠的。

我想也使用這個標準作爲子條件,因此要計算任何ActivityLog的行數並只保留count(*)= 2(所有參數都符合條件)的記錄,但是我無法找到如何與子查詢做到這一點。

有關如何解決上述問題的任何想法?在SQL我會做這樣的事情:

select activity_log_id from (
    select count(*) as ct, activity_log_id 
    from activity_log_parameter alp inner join activity_log al on alp.activity_log_id=al.id 
    where (alp.value='visitor' or alp.key<>'U') 
     and (alp.value='room1' or alp.key<>'L') 
    group by activity_log_id 
) as subq 
where subq.ct = 2 

感謝

回答

0

使用子查詢

DetachedCriteria subquery = DetachedCriteria.forClass(ActivityLogParameter.class, "alp") 
     .createAlias("activityLog", "al",JoinFragment.LEFT_OUTER_JOIN) 
     .setProjection(Projections.projectionList() 
       .add(Projections.count("id"), "alpId")); 

subquery = subquery.add(Property.forName("al.id").eqProperty("mainAl.id")); 

subquery = subquery.add(Restrictions.or(Restrictions.eq("alp.value", UValue), Restrictions.ne("alp.key", "L"))); 
subquery = subquery.add(Restrictions.or(Restrictions.eq("alp.value", LValue), Restrictions.ne("alp.key", "U"))); 

Criteria criteria = getCurrentSession().createCriteria(type, "mainAl"); 

criteria = criteria.add(Subqueries.eq(new Long(2), subquery)); 
解決
相關問題