Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Spring @transaction work on a concrete method of abstract class

From spring reference doc

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

Though it only talks about interfaces, abstract classes are considered as non-concrete as well.

So if i have an abstract class

public abstract class BaseService{
//here is a concrete method
@Transactional
public void updateData{
//do stuff using dao layer
}

and a concrete class which extends the class

public class SpecialService extends BaseService{
//body of class
}

Now if i call specialService.updateData() from my controller class will it be transactional?

like image 326
nayef Avatar asked May 19 '14 11:05

nayef


People also ask

Can abstract class have concrete methods?

Abstract class can have both an abstract as well as concrete methods. A concrete class can only have concrete methods. Even a single abstract method makes the class abstract.

Why applying Spring Transactional annotation on the concrete class or its methods is recommended rather than on interface?

Spring's recommendation is that you annotate the concrete implementations instead of an interface. It's not incorrect to use the annotation on an interface, it's just possible to misuse that feature and inadvertently bypass your @Transaction declaration.

On which can the @transactional annotation be applied?

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.

Can a concrete class override abstract methods?

As PMF mentioned, abstract methods must be overridden while concrete can be overridden.


1 Answers

Granting that you have actually configured Spring transaction management correctly, using @Transactional on an abstract superclass will work, since @Transactional is itself annotated with @Inherited and from it's Javadoc we have:

Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation.

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

To actually see that @Transactional is annotated with @Inherited check out it's Javadoc

like image 116
geoand Avatar answered Sep 20 '22 13:09

geoand