2012-04-19 82 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);