2011-06-01 75 views
5

使用Hibernate,我想更新基於條件的數據庫中的數據,但我得到了以下錯誤:「節點遍歷不能爲空」更新值與聯接

這裏是我的數據庫描述:

Account: id, email, password 
Member : id, account, team 
Team: id, current (and a reference to member => members) 

這裏是我的JPA:

UPDATE Team t SET t.current = :current LEFT JOIN t.members m WHERE t.current = :current_true AND m.account = :account 

我在做什麼錯? 如果我移動離開了集合加盟之前到:

UPDATE Team t LEFT JOIN t.members m SET t.current = :current WHERE t.current = :current_true AND m.account = :account 

我: 「期待SET,發現左」

如果刪除聯接:

UPDATE Team t SET t.current = :current WHERE t.current = :current_true AND t.members.account = :account 

我:「非法企圖取消收藏「。

什麼是更新值的正確方法?

感謝您的幫助!

回答

7

第4章中的JPA 2.0規範包含JPQL中所有支持的功能的詳細信息。這是「更新」語句的定義:

這些操作的語法如下:

update_statement ::= update_clause [where_clause] 
update_clause ::= UPDATE entity_name [[AS] identification_variable] 
        SET update_item {, update_item}* 
    update_item ::= [identification_variable.]{state_field | single_valued_object_field} = 
        new_value 
new_value ::= 
    scalar_expression | 
    simple_entity_expression | 
    NULL 

正如你可以看到,多個實體的支持是不是在這裏說。我想你必須找到一種不同的方式來做到這一點,也許創建一個方法來選擇你想要先更新的實體,然後迭代設置值的結果。或者你可以使用本地SQL更新。

+1

原生SQL更新將隨後者優先,這是愚蠢遍歷n的數據庫項,以使更新時,你可以用做一個查詢! (這是奇怪的JPA不包括它?!) – 2011-06-07 12:06:36

+0

@ cx42net即使如此,我沒有看到你在查詢中加入的需要。爲什麼不能在不使用成員字段的情況下在Team實體上編寫查詢?畢竟你使用了一個左連接,所以結果將是相同的,不是嗎? – 2011-06-07 12:16:55

+0

會員加入團隊和帳戶,我需要根據帳戶過濾更新,所以我想我需要加入會員。 – 2011-06-07 12:23:32

11

使用子查詢:

(未測試)

UPDATE Team t SET t.current = :current 
WHERE t.id in (select t1.id from Team t1 LEFT JOIN t1.members m WHERE t1.current = :current_true AND m.account = :account) 
+0

這將轉化爲sql中的一個子選擇,而且只要鍵不是複合鍵,就會工作。 – KarlP 2015-03-20 15:47:38

+0

非常感謝您的信息。它解決了我的問題! – curious1 2016-02-09 21:46:28

+0

是的!這工作。該死的!我很擔心一會兒。如果存在複合嵌入式密鑰,這也可以工作 – mike 2016-08-09 14:41:57