Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 春天的交易与流_Spring_Java 8 - Fatal编程技术网

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
    方法
  • 演示(1)

    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()