Multiple markers on this line when using @Transactional

Aubergine picture Aubergine · Nov 22, 2011 · Viewed 14k times · Source

for example:

@Transactional 
public boolean addPersonToDb(Person p) { // message on this line
 //some logic
}

Code compiles and runs with no problems.

Message itself: Multiple markers at this line

  • implements

com.pname1.pname2.pname3.pname4.PersonDAO.addPersonToDb

  • advised by

org.springframework.transaction.interceptor.TransactionInterceptor.invoke(org.aopalliance.intercept.MethodInvocation)

I can't really understand if it is an error or just a message, looking at other threads people get that as an error. I am just worrying if my transactions work.

Ok, the class implements interface and its method annotated as transactional , anything wrong with that?

Update: solved some minor errors, web app works but I still get that message(not in stack trace, but on the line breakpoint):

advised by org.springframework.transaction.interceptor.TransactionInterceptor.invoke(org.aopalliance.intercept.MethodInvocation)

Current situation:

        @Transactional
   public void registerNewUser(Person p) { // this gives message on line breakpoint - advised by ...; AND this method is implemented by interface

    pd.addPersonToDb(p);


}

@Transactional
public void blabla(Person p){ // this does not, as expected; AND it is not in interface

}

Do my transactions work or not? (I have no exceptions and web application runs and the methods work)

I can't understand if this message error or not?

Answer

Donal Fellows picture Donal Fellows · Nov 22, 2011

The issue with multiple markers is not a problem at all; it's purely informational. (The method is part of the implementation of an interface or abstract method, which you probably already knew, and it is intercepted by AOP because of the @Transactional annotation. I hope this doesn't surprise you…)

The error is because the class you are annotating doesn't implement a suitable interface (or interfaces), which would be necessary to use the built-in JDK proxy mechanism to put the AOP interceptors in place in the bean. (Bean-level interceptors are done through a proxy object that applies the transactional behavior and then delegates to the real object.) The JDK proxy mechanism only works with interfaces; intercepting anything else requires a different approach.

The two possible fixes for this are:

  1. Make the bean class implement a suitable interface that has all the methods of your class that are marked as @Transactional.
  2. Add cglib as a dependency, which Spring uses to dynamically write the classes that do the interception. (This is clever stuff.)

You only need to use one of these fixes, and the second one is very easy if you're using a build system like Maven; just update the dependencies. (Also, avoid doing calls to intercepted methods via this, whether explicit or not. That side-steps the AOP interception.)