Chris Williams
Chris Williams

Reputation: 12481

Seam @Transactional annotation not working?

I'm using the @Transactional annotation on a seam component similar to:

@Name( "myComponent" )
@AutoCreate
public class MyComponent
{
    public void something() {
        ...
        doWork();
    }
    ...
    @Transactional
    protected void doWork() {
        try {
            log.debug( "transaction active: " + Transaction.instance().isActive() );
        } catch (Exception ignore) {}

        // some more stuff here that doesn't appear to be inside a transaction
    }
}

In the "some more stuff" section, I'm modifying some Hibernate entities and then had a bug where an Exception was thrown. I noticed that the Exception wasn't causing the transaction to be rolled back (the modified entities were still modified in the db) so I added the "transaction active" logging. When this code executes, isActive() returns false.

Is there something I'm missing? Why isn't the transaction active?

In case it matters, I'm using the Seam component from inside another component that is using RESTEasy annotations to trigger my method calls.

Upvotes: 3

Views: 1893

Answers (1)

Gray
Gray

Reputation: 116888

I'm not familiar with how Seam works so my apologies in advance if this answer does not apply.

I noticed that the method that is @Transactional is protected. This implies to me that it is being called by another internal method.

With Spring's AOP, you mark the public methods with @Transactional which are wrapped and replaced with a transaction proxy. When an external class calls the public method, it is calling the proxy which forms the transaction. If the external class calls another public method that is not marked with @Transactional which then calls an internal method which is, there will be no transaction created because the proxy is not being called at all.

In Spring, even if you change your doWork() method to be public, the same problem would happen. No transaction because the proxy object is not being called. Method calls made inside of the class are not making calls to the proxy object.

A quick read of some documentation seems to indicate that, like Spring AOP, Seam is using CGLib proxying. The question is if it is able to proxy all methods -- even if they are called from within the proxied object. Sorry for wasting your time if this answer does not apply.

Upvotes: 6

Related Questions