2017-09-13 58 views
0

在我的實體我有這個領域JPA 2標準地圖鍵和值

@ElementCollection 
@CollectionTable 
@MapKeyColumn(name = "SERVER_ID") 
@Column(name = "IS_SYNC") 
private Map<String, Boolean> serverSyncs = new HashMap<>(); 

我試圖讓那些沒有與鍵的條目我的表的所有實體等於「SERVERID」 (在我的函數中作爲參數傳遞)或者有條目但值爲假。

這就是我現在

CriteriaBuilder builder = session.getCriteriaBuilder(); 
CriteriaQuery<T> criteriaQuery = builder.createQuery(clazz); 
Root<T> root = criteriaQuery.from(clazz); 
MapJoin<T, String, Boolean> mapRoot = root.joinMap("serverSyncs"); 

List<T> result = session.createQuery(
     criteriaQuery.where(
       builder.or(
         mapRoot.isNull(), 
         builder.not(mapRoot.key().in(serverId)), 
         builder.and(
           mapRoot.key().in(serverId), 
           mapRoot.value().in(false) 
         ) 
       ) 
     ) 
).list(); 

做的事情是我得到我的查詢此錯誤

無法找到CollectionPersister的角色:ca.tecsar.core.model .AbstractServerEntity.serverSyncs

問題是:我該如何用JPA 2.0 Criteria實現我想要的功能?

什麼,我需要找回

ID

例| SERVER_ID | IS_SYNC
1 | 0000000001 |真
1 | 0000000002 |虛假
2 | 0000000003 |虛假

如果我問SERVER_ID = 3,我應該得到實體1和2
如果我要求SERVER_ID = 2,我應該得到實體1
如果我要求SERVER_ID = 1,我什麼也得不到

+0

'mapJoin.value()'方法實際上沒有做任何事情,它們包含它以便查詢更好看。另外,'mapRoot.isNull()'引用地圖*值*,而不是地圖本身。我試着跳過'mapRoot.isNull()'(注意,使用標準API,默認的連接類型是'INNER JOIN',因此檢查'serverSync'的空值是多餘的)。至於你得到的錯誤,你的實體是否有可能涉及繼承層次?我認爲這可能是一個與Hibernate相關的bug。 – crizzis

+0

嗯,我該如何檢查價值?是的,我的模型擴展了AbstractServerEntity,它使用@MappedSuperclass註解。 – baskwo

+0

好吧,如果您將連接類型更改爲左連接,則我認爲檢查null鍵將是決定性的。無論如何,嘗試展開此特定實體的繼承層次結構;如果它有效,那麼你遇到的問題很可能是一個錯誤 – crizzis

回答

0

所以我不能用JPA 2 Criteria做到這一點,但我成功地使用了SQL Query。我有一個名爲PUNCH的表,映射表是PUNCH_SERVERSYNCS。

SELECT p.PUNCHID 
FROM PUNCH p 
LEFT JOIN PUNCH_SERVERSYNCS pss 
ON p.PUNCHID = pss.PUNCH_PUNCHID 
WHERE (pss.IS_SYNC = false AND pss.SERVER_ID = 'Server2') 
OR NOT EXISTS (SELECT p.PUNCHID FROM PUNCH_SERVERSYNCS pss2 WHERE 
pss2.PUNCH_PUNCHID = p.PUNCHID AND pss2.SERVER_ID = 'Server2') 
GROUP BY p.PUNCHID