Affects: 6.0.4


When class annotated with @Transactional annotation is registered in @Configuration class no actual transaction is started when calling methods while running in native image. When the same class is registered with @Service annotation everything works as expected. Both cases work fine in standard (non-native) run. This used to work in experimental version of spring-native but required manual registration of @Transactional beans. Provided example uses Spring Boot 3.0.2 for ease of configuration and when run in native mode the following exception occurs:

jakarta.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'merge' call

The class implements an interface and the interface is injected in CommandLineRunner and a method is called to save the entity.

spring-transactional-issue.zip

Comment From: sdeleuze

I understand it could be surprising, but the behavior you observe is expected because the type exposed but the @bean annotated method is DemoEntityService (the interface without@Transactional), the fact that DefaultDemoEntityService is the implementation is invisible to the AOT engine.

If you change the return type to DefaultDemoEntityService, it works as expected since it allows the AOT engine to infer the required hints. It should probably work as well with DemoEntityService and manual hints.

I will update the reference documentation to mention that limitation.

Comment From: agrancaric

Hello, thanks for a quick reply. This is just an example the issue is actually in a framework that I am maintaining and uses autoconfiguration to register default implementations. I am injecting interfaces to allow users to override default behaviour by providing another implementation. I've tried to annotate the interface with @Transactional and I've also tried registering hints for default implementation I get the same error:

java.lang.UnsupportedOperationException: CGLIB runtime enhancement not supported on native image. Make sure to include a pre-generated class on the classpath instead: com.example.springtransactionalissue.service.DefaultDemoEntityService$$SpringCGLIB$$0

And if I register hints for DefaultDemoEntityService$$SpringCGLIB$$0 transaction is not started. For me it seems that Springs default registration of @Transactional annotated classes is the problem here, and if it could be disabled for some class it could allow me to register a custom hint. Not sure is that possible somehow?

Comment From: sdeleuze

Indeed I can reproduce, I will have a deeper look.

Comment From: agrancaric

Ok, thanks.

Comment From: sdeleuze

You can make it work by moving the @Transactional issue to the interface and configuring spring.aop.proxy-target-class=false in Spring Boot (true by default).

Comment From: izeye

It seems that the "type: bug" label can be dropped as there's no bug fix here.

Comment From: sdeleuze

Done and I have updated the release notes accordingly.