TransactionRequiredException:执行更新/删除查询

pus*_*shy 11 hibernate jpa spring-mvc

我很难找到问题的解决方案.
我有一个服务类,其中包含一个在登录时设置验证标志的方法.

@Service("userRolesService")
@Repository
@Transactional
public class UserRolesService {
   public void verify() {
       repository.verifyUser();
   }
}
Run Code Online (Sandbox Code Playgroud)

我的存储库是一个SpringData CrudRepository,而verifyUser就是这样的

 @Modifying
 @Query("UPDATE user SET (verified = 1 WHERE verified=0)")
 public void verifyUser();
Run Code Online (Sandbox Code Playgroud)

在单元测试中直接调用代码时,一切正常.通过应用程序从我的身份验证提供程序调用它时,我得到以下异常:

javax.persistence.TransactionRequiredException:执行更新/删除查询

使用@Autowired注释将Service类注入到我的单元测试和身份验证提供程序中.测试本身没有任何有趣的注释本身,认证提供者也没有.

我是新鲜的想法,所以如果有人有线索,我会非常感激.

编辑:我现在检索所有未验证的用户,设置验证标志并使用存储库的save()方法,而不是调用verifyUser更新脚本.这有效,但非常难看,所以我愿意接受更好的建议.

EDIT2:

这里的每个请求是配置的持久性部分,我想这是最相关的,其余只处理身份验证.此配置用于单元测试和Web应用程序,唯一的区别是数据源是嵌入式H2 DB用于单元测试,而mysql用于Web应用程序.

<beans [..]>

    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          depends-on="persistenceInitializer">
        <property name="dataSource" ref="dataSource"/>
        <property name="persistenceUnitName" value="jpa"/>
        <property name="packagesToScan">
            <list>
                <value>com.example.model</value>
            </list>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="com.example.persistence.adapter.ConfigurationRetainingHibernateJpaVendorAdapter">
                <property name="database" value="${spring.hibernate.database}"/>
                <property name="generateDdl" value="${spring.hibernate.generateDdl}"/>
            </bean>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.DefaultComponentSafeNamingStrategy
                </prop>
            </props>
        </property>
    </bean>

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

    <jpa:repositories base-package="com.example.persistence.repository"/>

    <tx:annotation-driven/>

    <bean id="persistenceInitializer" class="com.example.persistence.init.NoOpInitializer"/>

</beans>
Run Code Online (Sandbox Code Playgroud)

另外,我有一个仅在Web应用程序中的配置,而不是单元测试:

<beans [..]>

    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:application.properties</value>
            </list>
        </property>
    </bean>

    <mvc:annotation-driven/>

    <mvc:default-servlet-handler/>

    <context:annotation-config/>

</beans>
Run Code Online (Sandbox Code Playgroud)

Mar*_*all 9

我想如果你<tx:annotation-driven/>进入包含的上下文<context:annotation-config/>,那么Spring会拿起你的@Transactional.该<tx:annotation-driven/>是一种后处理器,只有装饰豆在它定义的应用程序上下文.见我的答案在这里作进一步的解释.


小智 8

使用这种方式

@Modifying
    @Transactional 
    @Query(value ="delete from admindata where user_name = :userName AND group_name = :groupName",nativeQuery = true)
    public void deleteadminUser(@Param("userName") String userName,@Param("groupName") String groupName);
Run Code Online (Sandbox Code Playgroud)