我很难找到解决问题的方法。
我有一个服务类,其中包含一种在登录时设置验证标志的方法。
@Service("userRolesService")
@Repository
@Transactional
public class UserRolesService {
public void verify() {
repository.verifyUser();
}
}
我的存储库是 SpringData CrudRepository,verifyUser 类似于
@Modifying
@Query("UPDATE user SET (verified = 1 WHERE verified=0)")
public void verifyUser();
在单元测试中直接调用代码时,一切正常。通过应用程序从我的身份验证提供程序调用它时,出现以下异常:
javax.persistence.TransactionRequiredException
:执行更新/删除查询
@Autowired
使用注释将 Service 类注入到我的单元测试和身份验证提供程序中。测试本身没有任何有趣的注释,身份验证提供程序也没有。
我的想法很新鲜,所以如果有人有线索,我将非常感激。
编辑:我现在不再调用 verifyUser 更新脚本,而是检索所有未经验证的用户,设置已验证标志并使用存储库的 save() 方法。这有效,但非常难看,所以我愿意接受更好的建议。
编辑2:
这里的每个请求是配置的持久性部分,我想这是最相关的,其余的只处理身份验证。此配置用于单元测试和 Web 应用程序,唯一的区别是数据源是用于单元测试的嵌入式 H2 DB 和用于 Web 应用程序的 mysql。
<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>
此外,我有一个仅在网络应用程序中的配置,而不是单元测试:
<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>