13

I would like to use transactions done by aspects in spring-boot aplication, but so far I mostly found help for more "ordinary" setups...

What I've managed to set up so far?

I've got those annotations on main class:

@SpringBootApplication
@EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)

And this in my properties:

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

I'm starting application with java agents spring-instrument and aspectj-weaver and I can see aspects in stacktrace where I've used @Transactional so at least this is working.

Also, what is really strange, problem started only after I added second entity - first one worked without problem, but now I'm having this error:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

From what I've noticed beanFactory is null when invokeWithinTransaction is being run on TransactionAspectSupport - but it's being set during bean creation (and from what I've seen in debug when beanFactory is null TransactionAspectSupport won't start a transaction because it isn't able to get TransactionManager). I guess non-bean instance of TransactionAspectSupport is being created at some point and that may be the reason for my problem (but then how and why?)?

Update:

From what I've noticed @Transactional is handled by AnnotationTransactionAspect in one case, but by JtaAnnotationTransactionAspect in another.

Any ideas what I'm missing? Perhaps some magical property I should set?

Oh, and here are my dependencies, if that is important:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-instrument</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.7</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
</dependencies>
korda
  • 804
  • 7
  • 18
  • You don't need to set the current session context, as that is already done by spring. Also are you using plain hibernate or JPA? Can you also post how you are starting the application. – M. Deinum Dec 16 '15 at 11:52
  • Well... I'm starting it by simply running main class which has ` SpringApplication.run(Application.class, args);` in main method and annotations mentioned in question. Nothing fancy, since I try to keep my modifications to required minimum. EDIT: also, I run it with two -javaagent, set as described in question. – korda Dec 16 '15 at 12:27

1 Answers1

5

Ok. I'm an idiot, who didn't look what autoimport is doing.

I've used org.springframework.transaction.annotation.Transactional in one place and javax.transaction.Transactional in another.

After changing everything to spring provided @Transactional it started to work.

korda
  • 804
  • 7
  • 18