2012-06-06 46 views
1

比方說,那些都是我的實體:休眠(或沒有):查詢在先前填充可迭代<Entity>

Table1.java

@Entity 
public class Table1 { 

    // Many to one 
    private Table2 table2; 

    // Raw attributes 
    // ... 

} 

Table2.java

@Entity 
public class Table2 { 

    // Many to one 
    private Table3 table3; 

    // Raw attributes 
    // ... 

} 

Table3.java

@Entity 
public class Table3 { 

    // Raw attributes 
    private String lang; // "fr", "en", "de"... 

} 

當我想列出所有的Table1行其財產table2.table3.lang等於en的,我做的是這樣的:

Query query = entityManager.createQuery("SELECT t1 FROM Table1 t1 WHERE t1.table2.table3.lang = :lang"); 
query.setParameter("lang", "en"); 

這麼說,我怎麼能執行對以前填充Iterable<Table1>該查詢?它只是可行嗎?如果不用Hibernate,那麼用什麼?例如,即使我知道下面的代碼不能正常工作,這樣的:

Set<Table1> set = new HashSet<Table1>(); 
set.add(new Table1(INIT_DEFAULT_VALUES)); 
set.add(new Table2(INIT_DEFAULT_VALUES)); 
set.add(new Table3(INIT_DEFAULT_VALUES)); 

Query query = entityManager.createQuery("SELECT t1 FROM :set t1 WHERE t1.table2.table3.lang = :lang"); 
query.setParameter("set", set); 
query.setParameter("lang", "en"); 

對於那些誰不知道爲什麼我需要這樣的東西,我使用Apache Lucene到內執行用戶的搜索Table1行,之前也是由Lucene索引的。一旦我得到了一些結果,我必須在返回的列表上提出一些過濾器/排序,例如選擇鏈接的Table3實體的lang。

任何建議,將不勝感激:)

回答

1

Hibernate查詢翻譯成SQL查詢和數據庫中的執行。如果該集合包含不在數據庫中的實體實例,那麼Hibernate無法查詢它們。

如果這些實體實際上實體從數據庫中,你似乎預示着,那麼你可能只需使用一個IN條款:

Set<Long> ids = createSetOfIdsFromEntities(set); 
String hql = select t1 FROM Table1 t1 WHERE t1. id in (:ids) and t1.table2.table3.lang = :lang"; 
... 

但要確保你沒有太多的ID和你不要達到數據庫強加的限制(例如,Oracle將IN子句的元素限制爲1000)。

如果這些實體在內存中已經加載,你也可以只遍歷它們:

Set<Table1> found = new HashSet<Table1>(); 
for (Table1 t1 : set) { 
    if (t1.getTable2().getTable3().getLang().equals(theLang)) { 
     found.add(t1); 
    } 
} 
+0

謝謝!我會嘗試使用'IN'子句。 – sp00m