我使用 @EnableTransactionManagement
运行 Spring Boot 应用程序,并希望使用 @Transactional(readOnly = true)
进行某些数据库查询。
但我收到一条令人困惑的错误消息。 我正在使用 Spring、Spring Boot 和 Spring Data JPA。
MySpringBootApplication.java
@SpringBootApplication
@EnableTransactionManagement
@ComponentScan("com.deutscheboerse.regrephub")
@EntityScan(basePackages = "com.deutscheboerse.regrephub")
@EnableJpaRepositories(basePackages = "com.deutscheboerse.regrephub")
@Slf4j
public class MySpringBootApplication
{
... Some @Autowired variables ...
public static void main(String[] args)
{
SpringApplication.run(MySpringBootApplication.class, args);
}
...
}
MySpringBootApplicationConfiguration.java
@Configuration
@EnableEncryptableProperties
@EnableTransactionManagement
@EnableAsync
@Slf4j
public class MySpringBootApplicationConfiguration
{
... Some @Autowired variables ...
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource()
{
return DataSourceBuilder
.create(this.dataSourceProperties.getClassLoader())
.url(this.dataSourceProperties.getUrl())
.username(this.dataSourceProperties.getUsername())
.password(this.dataSourceProperties.getPassword())
.build();
}
...
}
MyBeanDao.java
@Repository
public interface MyBeanDao extends JpaRepository<MyBeanData, Long>
{
@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE))
@Query(value = "SELECT * FROM MY_TABLE", nativeQuery = true)
@Transactional(readOnly = true)
Stream<MyBeanData> streamAll();
}
MyBeanService.java
@Service
@Slf4j
public class MyBeanService extends AbstractService
{
@Autowired
public MyBeanService(...)
{
...
}
@Override
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public void handleRequest(Object request, Message msg)
{
try (Stream<MyBeanData> data = myBeanDao.streamAll())
{
...
}
catch (Exception e)
{
...
}
}
}
当我运行 SpringBootApplication 时,我将收到以下日志消息/错误:
[TransactionInterceptor:474] Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.streamAll]
[TransactionInterceptor:517] Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.streamAll] after exception: org.springframework.dao.InvalidDataAccessApiUsageException: You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction.
[RuleBasedTransactionAttribute:131] Applying rules to determine whether transaction should rollback on org.springframework.dao.InvalidDataAccessApiUsageException: You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction.
[RuleBasedTransactionAttribute:148] Winning rollback rule is: null
[RuleBasedTransactionAttribute:153] No relevant rollback rule found: applying default rules
首先 JPA 打开一个事务并立即关闭它,但有一个异常,我想在没有周围事务的情况下执行流式查询方法。 有人以前有过这个吗?!
最佳答案
我修好了!
这是 spring 上下文的问题。
当我初始化 MyBeanService 时,我将 bean 存储到具有相应请求对象的 HashMap 中。
dispatcher.put(MyBeanRequest.class, this);
...
((MyAbstractService) dispatcher.get(MyBeanRequest.class).handleRequest(...);
当我在 spring 上下文中搜索 bean 时,它起作用了:
dispatcher.put(MyBeanRequest.class, this.getClass());
...
((MyAbstractService) appContext.getBean(dispatcher.get(requestObject.getClass()))).handleRequest(...);
关于java - Spring数据JPA : InvalidDataAccessApiUsageException for @Transactional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48322731/