robert_difalco
robert_difalco

Reputation: 4914

Strange Spring Transaction Behavior

I'm having a difficult time understanding Spring Transactions. First off, I am trying to use as little of Spring as possible. Basically, I want to use @Transactional and some of its injection capabilities with JPA/Hibernate. My transactional usage is in my service layer. I try to keep them out of test cases. I use CTW and am spring-configured. I have component scan on the root of my packages right now. I also am using Java configuration for my datasource, JpaTransactionManager, and EntityManagerFactory. My configuration for the JpaTransactionFactory uses:

        AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );

I do not use @EnableTransactionManagement.

Unfortunately, I'm having a hard time understanding the rules for @Transactional and can't find an easy page that describes them simply. Especially with regards to Session usage. For example, what if I want to use @Transactional on a class that does not have a default no-arg constructor?

The weirdest problem I'm having is that in some of the POJO service classes Transacitonal works great while in others I can see the transactions being created but operations ultimately fall saying that there is "no session or the session has been closed". I apologize for not having code to reproduce this, I can't get it down to a small set. This is why I am looking for the best resources so I can figure it out myself.

For example, I can have a method that gets a lazily fetched collection of children, iterates through it and puts it into a Set and returns that set. In one class it will work fine while in another class also marked with @Transactional it will fail while trying to iterate through the PersistentSet saying that there is no session (even though there IS a transaction).

Maybe this is because I create both of these service objects in a test case and the first one is somehow hijacking the session?

By the way, I have read through the spring source transaction documents. I'm looking for a clear set of rules and tips for debugging issues like this. Thanks.

Upvotes: 2

Views: 557

Answers (1)

Vincent
Vincent

Reputation: 1035

Are you sure you loaded your parent entity in the scope of the very transaction where you try to load the lazy children? If it was passed in as parameter for example (that is, loaded from outside your @Transactional method) then it might not be bound to a persistence context anymore...

Note that when no @Transactional context is given, any database-related action may have a short tx to be created, then immediately closed - disabling subsequent lazy-loading calls. It depends on your persistence context and auto-commit configurations.

To put it simply, the behaviour with no transactional context being sometimes unexpected, the ground rule is to always have one. If you access your database, then you give yourself a well-defined tx - period. With spring-tx, it means all your @Repository's and @Services are @Transactional. This way you should avoid most of tx-related issues.

Upvotes: 1

Related Questions