Announcement Announcement Module
No announcement yet.
Testing and Transactional Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Testing and Transactional

    I'm new to Spring and having a difficult time figuring out @Transactional. My basic setup:

    JPA, Java Configuration, CTW, AnnotationTransactionAspect.aspectOf(), spring-configured, Hibernate, component scan on everything for now.

    Test runs with SpringJUnit4ClassRunner. Each Test class is annotated with:

    @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD )
    I have a parent entity and a child entity. There is a ONETOMANY relationship between them. Though I don't think this is relevant.

    My test methods are NOT annotated with @Transactional. I want to make sure that my service layer is using flush, et al correctly so I need committed transactions between operations within the test method.

    My @Transactional usage is in my service layer. Furthermore, the service layer is injected into a fluent interface that the test uses. This allows me to do things like this:

    Code: parent.getId() ).getChildrenNames();
    Here's a brief version of ParentOperations:

        public class ParentOperations {
           private ParentService service;
           private Parent parent;
           public static ParentOperations id( Long id ) {
              ParentOperations ops = new ParentOperations();
              ops.parent = ops.service.findById( id );
              return ops;
           public Set<Child> getChildren() {
              return service.getChildrenOf( this.parent );
    There's a bunch more to it but you get the idea. All the methods in ParentService are @Transactional. The #getChildrenOf method simply populates a HashSet using the result of parent.getChildren() which is using a LAZY fetch but should be fine since it is done within a transaction.

    So here's the rub. In my test method, if I persist the parent first and then do a parent.getId() ).getChildren() I get an exception in ParentService#getChildrenOf when trying to build the Set of children with Spring saying that during the lazy load that there is "no session or session has been closed".

    In the logging I can see that Spring "found a thread-bound entity manager" and is "participating in the current transaction." But I can see after the #persist call that the EntityManager has been closed.

    As you might imagine if I annotate the WHOLE test method all is well. But if I do that I cannot ensure that stuff is really happening correctly in the database verses just the cache using object references.

    How can I have an active transaction here but no session?

    Appreciate any pointers.

  • #2
    Okay, I've got this narrowed down further. If in my service I have these methods (all transactional):

       public Parent findById( Long id );
       public Set<Child> getChildrenOf( Parent parent );
    And I have another method in this service that uses the two methods above as in:

        public Set<Child> getChildrenOf( Long id ) {
           Parent parent = findById( id );
           return getChildrenOf( parent );
    Then in client code, I can call that method and it works. But if I try to call #findById and then #getChildrenOf I get the "no session for transaction" exception. But if my service has a method that calls them together it works fine.

    Can anyone simply explain this to me? In my client code both methods are called on the same instance of my service.