Trying to collect and understand the main points of #Transactional annotation and crossed one point. So, the main things that we need to keep in mind when using Transactional annotation are:
Transactional annotation can be applied only to public methods [according to Does Spring #Transactional attribute work on a private method?
Transactional annotation should be applied to the concrete classes instead of interfaces [according to Where should I put #Transactional annotation: at an interface definition or at an implementing class?
Transactional annotation should be applied on the Service level [according to Spring #Transactional Annotation Best Practice
If you want to exclude some public method from being annotated with Transactional when whole class is annotated you can use some propagation strategies [according to Transactional annotation on whole class + excluding a single method
Unfortunately I didn't find the answer to the question: Where it is better to put Transactional annotation - to the class or method? We can consider different situations, but mostly i am interested in the one when we have several methods which must have this annotation and some which don't.
Plus, maybe you would like to add some points to this list, that would be really great.
Here is a list of pros and (implicitly) cons I can think of.
Pro Method Level:
Easy to read: You look at a method and can tell that it is transactional without having to look at the class, its implemented interfaces or super-classes.
Explicit: The annotation clearly tells you that the method is meant to be transactional. It is not just transactional because all methods in the class are transactional.
Less unintended merging of (otherwise) independent transactions: If you call multiple transactional methods from a method that is (implicitly) transactional, then the outer transaction defines the whole transaction (unless the propagation settings are like REQUIRES_NEW or so). While this is in many cases no problem, I have seen projects getting into serious trouble due to this in the long run. Especially when it comes to pessimistic locking, it is crucial to keep transactions as independent and small as possible, so transactions need only few locks and the locks are released as soon as possible.
Pro Class Level:
Less repetitive: If you put the annotation on the class level, you do not have to annotate each and every transactional method. Some people argue that putting the annotation on each transactional method is against the DRY principle. However, IMHO, if this is against the DRY principle, then Java's private/protected/public modifiers are, too.
In my opinion it is better to mark each method with #Transactional annotation separately (to indicate that this method is updating something) instead of marking whole class. This will produce more code and can be redundant in some cases but imagin that you have for example 10 methods in your service. Nine of those methods are updating something and one is only reading. Your code is using ORM (for example Hibernate) and you have some objects managed by Hibernate in your method. During adding new logic you accidentaly changed one field in object managed by Hibernate. In this case hibernate will fire update sql insturction in method which should only read. It may produce bug which is hard to find.
Related
Our applications using Spring Cache and need to know if response was returned from cache OR it was actually calculated. We are looking to add a flag in result HashMap that will indicate it. However whatever is returned by method, it is cached so not sure if we can do it in calculate method implementation.
Is there any way to know if calculate method was executed OR return value coming from cache when calling calculate method?
Code we are using for calculate method -
#Cacheable(
cacheNames = "request",
key = "#cacheMapKey",
unless = "#result['ErrorMessage'] != null")
public Map<String, Object> calculate(Map<String, Object> cacheMapKey, Map<String, Object> message) {
//method implementation
return result;
}
With a little extra work, it is rather simple to add a bit of state to your #Cacheable component service methods.
I use this technique when I am answering SO questions like this to show that the value came from the cache vs. the service method by actually computing the value. For example.
You will notice this #Cacheable, #Service class extends an abstract base class (CacheableService) to help manage the "cacheable" state. That way, multiple #Cacheable, #Service classes can utilize this functionality if need be.
The CacheableService class contains methods to query the state of the cache operation, like isCacheMiss() and isCacheHit(). Inside the #Cacheable methods, when invoked due to a "cache miss", is where you would set this bit, by calling setCacheMiss(). Again, the setCacheMiss() method is called like so, inside your #Cacheable service method.
However, a few words of caution!
First, while the abstract CacheableService class manages the state of the cacheMiss bit with a Thread-safe class (i.e. AtomicBoolean), the CacheableService class itself is not Thread-safe when used in a highly concurrent environment when you have multiple #Cacheable service methods setting the cacheMiss bit.
That is, if you have a component class with multiple #Cacheable service methods all setting the cacheMiss bit using setCacheMiss() in a multi-Threaded environment (which is especially true in a Web application) then it is possible to read stale state of cacheMiss when querying the bit. Meaning, the cacheMiss bit could be true or false depending on the state of the cache, the operation called and the interleaving of Threads. Therefore, more work is needed in this case, so be careful if you are relying on the state of the cacheMiss bit for critical decisions.
Second, this approach, using an abstract CacheableService class, does not work for Spring Data (CRUD) Repositories based on an interface. As others have mentioned in the comments, you could encapsulate this caching logic in an AOP Advice and intercept the appropriate calls, in this case. Personally, I prefer that caching, security, transactions, etc, all be managed in the Service layer of the application rather than the Data Access layer.
Finally, there are undoubtedly other limitations you might run into, as the example code I have provided above was never meant for production, only demonstration purposes. I leave it to you as an exercise to figure out how to mold these bits for your needs.
I have written a MapStruct mapper which has two methods with the #AfterMapping annotation. Depending on the context, I want only one of these methods to be executed before the end of the mapping.
With regard to this, the MapStruct documentation states:
All after-mapping methods that can be applied to a mapping method will
be used. #Qualifier / #Named can be used to filter the methods to use.
Regarding #Named, the documentation contains a good example on how to use this annotation in order to perform two different kinds of mappings for a bean property. But I do not understand how to adapt this kind of distinction to my two after-mapping methods.
You can specify the qualifier in the #BeanMapping annotation in order to make it applicable to life cycle method. Note: I recently fixed an issue in this area on the master. Don't think that's released already. Forgot the exact issue (not able to look it up currently)
I'm trying to somehow 'debug' my application that use the spring boot cache annotations and for that I would like to know how to find the class that actually implements the interface Cacheable, CacheConfig, etc.
My idea is to confirm that the cache is being populated, emptied etc.
Thanks a lot for your help,
#Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method. In its simplest form, the annotation declaration requires the name of the cache associated with the annotated method:
#Cacheable("books")
public Book findBook(ISBN isbn) {...}
In the snippet above, the method findBook is associated with the cache named books. Each time the method is called, the cache is checked to see whether the invocation has been already executed and does not have to be repeated. While in most cases, only one cache is declared, the annotation allows multiple names to be specified so that more than one cache are being used. In this case, each of the caches will be checked before executing the method - if at least one cache is hit, then the associated value will be returned.
For more information read the following;
https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache
Spring used ConcurrentHashMap as the default cache implementation.
public class ConcurrentMapCache extends AbstractValueAdaptingCache
If, on the other hand, you need different cache, then Spring also comes with a built in ehCache wrapper. The good news is that swapping between Spring's caching implementations is easy. In theory itβs all a matter of configuration.
I'd like to wrap/unwrap my Entity each time it's loaded or persisted. I got to know that I cannot do it using JPA listeners since they can only perform an action on the object and not swap it with the other. The natural solution would be to use an Aspect. But are there particular methods that I can pointcut? The thing is that the entity to be wrapped/unwrapped can be a field of another entity...
EDIT:
I found out that you cannot do this using Spring AOP because EntityManager is not spring-managed (why?) - see here. To make it work I would have to define EntityManager bean explicitely but it is not recommended in that post - again, why? How to do that anyway? On the other hand why does they state that created EntityManager is application-managed? See spring API documentation
Try to pointcut the getters and setter that use the entity class. Methods that retrieve entities from EntityManager, best way to achieve this is create new annotation and put over all the methods that could retrieve a instance for that class, then use the #annotation support pointcut:
#annotation - limits matching to join points where the subject of the
join point (method being executed in Spring AOP) has the given
annotation
Also to obtain the modifying entity you could do something like this.
Get method arguments using spring aop?
Sometimes you need access in the advice body to the actual value that was returned. You can use the form of #AfterReturning that binds the return value
Hibernate Search, Hibernate, Struts2... I see more examples... In same examples I see the annotation on the field.. Other on the get/set method.. There are differences? Or is casual..
I hope that is not a stupid question!
Saluti!
Luigi
The difference depends on the annotation and how it is used. For example, in Spring you can use the #Controller annotation only on a class. This tells Spring that the class is a controller.
As far as methods are concerned, #RequestMapping is an annotation that goes on a method. For properties, you can have validation annotations like #NotNull (in Hibernate validator).
Annotations are definitely not casual; they carry meaning and can affect the way the code behaves.
From the Java documentation regarding annotations:
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Annotations have a number of uses,
among them:
Information for the compiler β Annotations can be used by the
compiler to detect errors or suppress
warnings.
Compiler-time and deployment-time processing β Software tools can
process annotation information to
generate code, XML files, and so
forth.
Runtime processing β Some annotations are available to be
examined at runtime.
Annotations can be applied to a
program's declarations of classes,
fields, methods, and other program
elements.
You can specify what an annotation can annotate by specifying the the elements (using a #Target annotation) when you define your own annotation.
This really depends on the code that interprets the annotations. It can of course make a difference, but the annotations you are talking about are probably meant to annotate a "property", which is something that technically does not exist in Java.
Java has fields and methods, but these are used to simulate properties under the "Java Bean" conventions, i.e. you have a public setX() and a getX() method that often (but not always) write and read a private field x. They're tied together via a naming condition, not a language mechanism.
Because of that, most frameworks that use annotations for such properties (e.g. for persistence mapping or dependency injection) are flexible and allow you to annotate either the field or the get or set method.