Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice @Transactional does not start an transaction

Tags:

java

guice

I have started to use Guice method-level transactions like described here. I have a message like

@Inject
private EntityManager entityManager;

@Transactional
public UserSession createSession(User user, String browser) {
    UserSession session = new UserSession(user, browser);
    entityManager.persist(session);
}

From the short description i thought wis should be enough. But i get an error cause no transaction is started. It works only if i start and commit it by myself.

The Object is created by Guice on the Start of my Application in an initializer. the same Instance is used for each request.

Why is it not working?

like image 223
Mike Petersen Avatar asked Dec 31 '12 01:12

Mike Petersen


People also ask

Can @transactional annotation only be used at class level?

Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.

What does @transactional do in spring?

The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.

What happens if one @transactional annotated method is calling another @transactional annotated method on the same object instance?

If you call a method with a @Transactional annotation from a method with @Transactional within the same instance, then the called methods transactional behavior will not have any impact on the transaction.

When @transactional is used on top of a class?

@Transactional can be used on top of class or method, in classes or interfaces. If used on top of class, it applies to all public methods in this class.


1 Answers

@Transactional method annotations work through AOP, in which Guice fulfills a request for Foo by creating a proxy object that intercepts those annotated method calls and (optionally) forwards them to the actual object. Make sure that the following are true:

  1. You have created the object with the @Transactional method through Guice, since Guice otherwise won't have any chance to provide the proxy instead.

  2. Neither the class nor the method is marked final, since AOP can't override those easily.

  3. You have installed JpaPersistModule, or some other form of PersistModule. Note from that source code that this module is actually what binds the MethodInterceptor to the @Transactional annotation.

If this doesn't fit your needs exactly, remember that you can always go with the AOP documentation to write your own method interceptor. Good luck!

like image 195
Jeff Bowman Avatar answered Nov 16 '22 01:11

Jeff Bowman