2012-04-19 86 views
35

我配置並運行了spring-data和hibernate。我可以使用spring-data保存記錄,但出於某種原因,我無法運行將更新表中所有布爾字段的查詢。使用@Query更新彈簧數據jpa中的布爾值,使用@Query,休眠

我嘗試這樣做:

@Query("update Content v set v.published = false where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
         @Param("section") String section); 

我也試過這樣:

@Query("update Content v set v.published = 0 where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
         @Param("section") String section); 

參數師和部分正在變成現實,但在桌子上沒有變化。

p.s.我也在使用mysql數據庫。

回答

108

我使用Spring 3.1和Spring JPA數據。我遇到了類似的問題。在嘗試更新1個查詢中的多個記錄時,我經常發生錯誤。

所以,我有這樣的事情。

@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

錯誤:

org.hibernate.hql.QueryExecutionRequestException: Not supported for DML operations 

所以,google搜索了一會兒後,我發現,你必須增加@Modifying。

@Modifying 
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

但後來我發現了以下錯誤:

...  
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; 
nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 
... 

所以,我想我的問題是現在交易的問題,我又回到了谷歌研究,結果發現了,你必須現在添加@Transactional。看起來@修飾也需要@Transactional。

@Modifying 
@Transactional 
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

但後來我得到了以下錯誤:

No value for key [org.apache.commons.dbcp.BasicDataSource (...) ] bound to thread 

再次我GOOGLE了一段時間,得出的結論,我的配置是錯誤的,它被證明是真實的。我錯過了一些XML配置。

<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> 
    <beans:property name="entityManagerFactory" ref="entityManagerFactory"/> 
</beans:bean> 

<tx:annotation-driven transaction-manager="transactionManager"/> 

這是漫長的旅程,但我終於得到它的工作。我希望這會幫助別人,試圖「付出代價」,因爲其他許多人用他們美妙的博客,答案和評論幫助我。

+2

不應該是必需的,因爲Spring Data會自動將基於註釋的事務應用於存儲庫接口。 – 2013-03-29 15:23:01

+1

也確保註解是從org.springframework.transaction.annotation中導入的,而不是javax – barryku 2014-09-23 22:04:14

+0

我在Spring JPA存儲庫中使用與以下類完全相同的配置,但在創建bean時出錯。 (不是一個特定的錯誤,它只是說存儲庫不能創建)。爲什麼會這樣? '@Repository 接口IContactRepository延伸PagingAndSortingRepository <接觸,龍> { \t @Modifying \t @Query( 「從觸點c刪除其中c.circle.id =:circleId」) \t空隙deleteAllMembersOf(@Param( 「circleId」)Long circleId); }' – noego 2015-03-03 23:07:25

8

要執行修改查詢你需要一個額外的@Modifying註釋作爲reference documentation這樣概括的方法:

@Modifying 
@Query("update Content v set v.published = false where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
        @Param("section") String section); 
+0

所以...爲你做或不工作?我有點困惑你說什麼;) – 2012-04-22 09:08:38

+1

對不起奧利弗,有點累,我犯了一個錯字。不,它沒有幫助。按照我的理解,如果您的存儲庫註釋爲只讀,則此選項「@Modifying」很有用。通過這種方式,您可以讓我的存儲庫主要是隻讀的,但它仍然允許您在其中使用寫入方法。 – aki 2012-04-25 15:12:17

+0

這與'readOnly'無關 - 至少不是直接。 'readOnly'是關於事務的,'@Menifying'是關於'EntityManager'上的一個調用。嘗試在只讀事務中執行修改方法當然沒有意義。 – 2012-04-26 07:52:29

3

對於我來說,有以下注釋工作:

@Modifying 
@Query("update JsonContactImport x set x.isImported = true where x.id in :ids") 
@Transactional 
void updateImported(@Param("ids") List<Long> ids); 
7

對於我來說,它具有以下注釋工作:

@Modifying 
@Query("update User u set u.active=1 where a.id=?1") 
@Transactional 
void activeUser(Long id);