I try to understand why this code doesn\'t work
In component:
@PostConstruct
public void runAtStart(){
testStream();
}
@Transactional(readOnly
One key thing about Spring is that many annotated features use proxies to provide the annotation functionality. That is @Transactional
, @Cacheable
and @Async
all rely on Spring detecting those annotations and wrapping those beans in a proxy bean.
That being the case, a proxied method can only be used when invoked on the class and not from within the class. See this about the topic.
Try:
@Transactional
method from another class in your context, or @Transactional
method that way.To demonstrate (1):
public class MyOtherClass {
@Autowired
private MyTestStreamClass myTestStreamClass;
@PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `@Transactional`
myTestStreamClass.testStream();
}
}
To demonstrate (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);
}
}
}