2013-07-02 27 views
2

鑑於2個表Hibernate的標準 - 入世對未映射實體

@Entity 
@Table 
public class SomeEntity { 
    @Id 
    private Long someId; 

    @Column 
    private String text; 

    @ManyToMany 
    @JoinTable(name = "map", joinColumns = @JoinColumn(name = "someId"), inverseJoinColumns = @JoinColumn(name = "eventId")) 
    private Set<SomeEntityEvent> events; 

    // get/set 
} 

@Entity 
@Table 
public class SomeEntityEvent { 
    @Id 
    private Long eventId; 

    @Column 
    private Calendar date; 

    // get/set 
} 

Hibernate會產生如下表(請注意,我沒有對地圖實體)

some_entity: someId | text 
some_entity_event: eventId | date 
map: someId | eventId 

我想使用Criteria API來獲取屬於某個SomeEntity的所有SomeEntityEvent實例,該實例按日期排序並在某個範圍內。通過SQL,我可以簡單地做

SELECT * 
FROM some_entity_event e 
NATURAL JOIN map 
WHERE map.someId = [ my field ] 
ORDER BY e.date DESC 
LIMIT 0, 100; 

由於我沒有Map實體(或SomeEntity參考),我不知道如何建立一個Criteria等效於上面的查詢。下面的標準讓我全部SomeEntityEvent。我只想要那些屬於SomeEntity的那些。

Criteria criteria = getCurrentSession().createCriteria(SomeEntityEvent.class); 
criteria.addOrder(Order.desc("date")) 
    .setFirstResult(firstResult) 
    .setMaxResults(maxResults); 
return criteria.list(); 

這可能與Criteria?如果是的話,你如何執行該加入?

回答

2

首先,從HQL開始。當查詢必須基於一組...條件動態組合時,條件很有用。即使你絕對要使用標準API,使用HQL查詢並翻譯它也更容易。

OK,所以你要屬於按日期和某些範圍內有序一定SomeEntity事件:

select event from SomeEntity entity 
join entity.events event 
where entity.id = :entityId 
and event.date between :startDate and :endDate 
order by event.date 

現在你可以將其轉化爲標準。問題是標準API不允許選擇除根實體之外的任何其他實體,並且由於您沒有從SomeEntityEvent到SomeEntity的關聯,所以您被卡住了。

因此,我的建議是:在HQL中執行此操作,或將該關聯設爲雙向。如果是雙向的,你可以寫的HQL這樣的查詢:

select event from SomeEntityEvent event 
join event.entities entity 
where entity.id = :entityId 
and event.date between :startDate and :endDate 
order by event.date 

而且它可以很容易地轉換爲標準:

Criteria c = session.createCriteria(SomeEntityEvent.class, "event"); 
c.createAlias("event.entities", "entity"); 
c.add(Restrictions.eq("entity.id", entityId); 
c.add(Restrictions.between("event.date", startDate, endDate); 
c.addOrder("event.date"); 

注意HQL查詢的每一部分如何直接轉化爲類似標準指令。

+0

我想我要結束添加雙向關聯。我原本不是因爲我不希望用戶能夠關注該關聯。我在查看其他問題,除了最後將「ResultTransformer」設置爲「DistinctRootEntityResultTransformer.INSTANCE」之外,您還可以提供相同的答案。那是什麼? –

+0

另外,在第一個HQL選項中,'join'是否像「自然連接」一樣執行,只映射相等的ID? –

+0

它避免了在結果中多次發生相同的事件。它與HQL中的「select distinct」基本相同。你可能確實需要這個。忘了它。 –