Spring 春天的交易与流
我试图理解为什么这个代码不起作用 在组件中:Spring 春天的交易与流,spring,java-8,Spring,Java 8,我试图理解为什么这个代码不起作用 在组件中: @PostConstruct public void runAtStart(){ testStream(); } @Transactional(readOnly = true) public void testStream(){ try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){ top
@PostConstruct
public void runAtStart(){
testStream();
}
@Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
@PostConstruct
public void runAtStart(){
testStream();
}
@事务(只读=真)
公共void testStream(){
try(Stream top10ByFirstName=personRepository.findTop10ByFirstName(“Tom”)){
top10ByFirstName.forEach(System.out::println);
}
}
和存储库:
public interface PersonRepository extends JpaRepository<Person, Long> {
Stream<Person> findTop10ByFirstName(String firstName);
}
公共接口PersonRepository扩展了JpaRepository{
流findTop10ByFirstName(字符串firstName);
}
我得到:
org.springframework.dao.InvalidDataAccessApiUsageException:您正在尝试执行一个流查询方法,而没有一个使连接保持打开的周围事务,以便流可以实际使用。确保使用流的代码使用@Transactional或任何其他方式声明(只读)事务
Spring的一个关键点是,许多带注释的特性使用代理来提供注释功能。也就是说,
@Transactional
、@Cacheable
和@Async
都依赖于Spring检测这些注释并将这些bean包装到代理bean中
在这种情况下,代理方法只能在类上调用时使用,而不能在类内调用。关于主题,请参见
尝试:
@Transactional
方法,或@Transactional
方法public class MyOtherClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional`
myTestStreamClass.testStream();
}
}
@Component
public class MyTestStreamClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional` since it's self-autowired
myTestStreamClass.testStream();
}
@Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
}
演示(2):
public class MyOtherClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional`
myTestStreamClass.testStream();
}
}
@Component
public class MyTestStreamClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional` since it's self-autowired
myTestStreamClass.testStream();
}
@Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
}
@组件
公共类MyTestStreamClass{
@自动连线
私有MyTestStreamClass MyTestStreamClass;
@施工后
public void runAtStart(){
//这将调用“@Transactional”的代理拦截器,因为它是自连线的
myTestStreamClass.testStream();
}
@事务(只读=真)
公共void testStream(){
try(Stream top10ByFirstName=personRepository.findTop10ByFirstName(“Tom”)){
top10ByFirstName.forEach(System.out::println);
}
}
}
@Transactional
需要Spring AOP。默认的SpringAOP实现使用标准JDK代理,它不适用于类内调用。这在本手册中有相当详细的介绍。如果在同一个类中需要AOP语义,请考虑使用AspectJ代理。没有其他干净的概念了吗?P//这是个好办法。我尝试使用((RunAtStart)AopContext.currentProxy()).testStream()正如@manith提到的,但这给了我:`调用init方法失败;嵌套异常为java.lang.IllegalStateException:找不到当前代理:将建议的上的“exposeProxy”属性设置为“true”以使其可用`