我试图理解为什么这段代码不起作用
在组件中:
@PostConstruct
public void runAtStart(){
testStream();
}
@Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
和存储库:
public interface PersonRepository extends JpaRepository<Person, Long> {
Stream<Person> findTop10ByFirstName(String firstName);
}
我得到:
org.springframework.dao.InvalidDataAccessApiUsageException:您正在尝试在没有周围事务的情况下执行流查询方法,该事务使连接保持打开状态,从而可以实际使用Stream。确保使用流的代码使用@Transactional或其他任何声明(只读)事务的方式。
答案 0 :(得分:1)
关于Spring的关键一点是,许多带注释的功能都使用代理来提供注释功能。即@Transactional
,@Cacheable
和@Async
都依赖于Spring检测这些注释并将这些bean包装在代理bean中。
在这种情况下,仅当在类中的上调用该代理方法时,才可以使用该方法。有关该主题,请参见this。
尝试:
@Transactional
方法,或者@Transactional
方法。演示(1):
public class MyOtherClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional`
myTestStreamClass.testStream();
}
}
演示(2):
@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);
}
}
}