Query about Spring Transaction configuration and propagation - java

IN spring docs it's written
The most important concepts to grasp with regard to the Spring Framework's declarative transaction
support are that this support is enabled via AOP proxies, and that the transactional advice is driven by
metadata (currently XML- or annotation-based).
So If i use
<tx:annotation-driven proxy-target-class="true" order="100"/>
in config file and not use #Transactional annotation on my beans. Would transaction still be supported, as I am using AOP and transaction Interceptor should be built-in to my AOPs thus no use of explicitly using #Transactional annotation.
Thanks,

No, you'd still have to use the #Transactional annotation. AOP proxy is only used to inject the transaction related code into your code.

< tx:annotation-driven /> is used to auto detect the '#Transactional' annotation .So it's necessary to have one . Reference here.
The proxy-target-class="true" decides whether Spring should use JDK dynamic proxies or CGLIB class based proxies . See the reference for more info . Basically if your class implements atleast one interface, JDK dynamic proxies are used . If you have a class MyDaoImpl extends MyDao and in your service , you inject the dao reference via MyDaoImpl myDaoImpl , JDK dynamic proxies will not work if the annotations are on your interface as class bases proxies are created with proxy-target-class="true" and #Transactional annotation is not inherited .
The reason why your queries seem to work without #Transactional may be because you are using hibernate template which opens and closes the transactions internally . From Spring 3 , it is recommended to inject sessionFactory directly and not to use hibernate template .
Hope this helps.

Related

Where to specify #Transactional annotation in a Spring Boot app?

In the context of a recent Spring Boot app (v. 2.7.0), there are a number of options for where the #Transactional annotation is applied
Controller or Service?
Almost universally it seems that service is recommended, but it's not entirely clear why.
Implementation class or interface?
Assuming we choose to apply the annotation to our services and those services implement an interface, should we annotate the service interface or the implementation class?
In older versions of the Spring docs, it was recommended to annotate the class
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.
But this advice does not appear in the 5.2.X version of the docs, so I'm wondering if it still applies? Based on my testing it seems that applying the #Transactional annotation to interfaces does work in a Spring Boot app with the default proxying behaviour.
#Transactional is most commonly used at service level, though there is nothing stopping you from making your controller methods transactional. It really depends on how you structure your application.
IMHO making your service layer transactional is a better approach. It is typically at this level that you might be calling other persistence methods (DAOs, repositories, etc). There could be reads/writes across multiple tables, so it makes the service layer a good place to define transaction boundaries.

Does hibernate interceptor need any configuration prior to use?

I'm trying to get Audit records from hibernate using Interceptor class which extends EmptyInterceptor. My question is, does hibernate automatically configure and call methods in Interceptor class or do i have to make any configuration whatsoever in hibernate.cfg.xml or anywhere?
Yes. Exactly how you configure the Hibernate Interceptor depends on how you use Hibernate in your application - Via Spring JPA etc.

Enable Spring AOP or AspectJ

This is following on from this question:
Spring autowired bean for #Aspect aspect is null
My initial understanding was that when using Spring AOP, classes annotated with #Aspect are created as spring managed beans, so dependency injection would work as normal. However it seems that an object with the #Aspect annotation is created as a singleton outside the spring container, hence me having to configure it in XML like so in order to enable it as a spring managed bean:
<bean id="aspect" class="com.mysite.aspect" factory-method="aspectOf" />
This has now completely confused me. I thought the following configuration would use spring AOP:
<context:component-scan base-package="com.mysite.aspectPackage"/>
<aop:aspectj-autoproxy/>
So it would scan for #Aspect annotations using component-scan creating aspect beans, and then autoproxy would create a beanPostProcessor which proxies all beans within my context with the appropriate advice. I then thought to enable aspectJ I would need a completely different XML configuration (which incidentally I can't seem to find an example of in the documentation). It would be this configuration that uses aspectJ to create aspects that would be outside of my container or which work by manipulating bytecode rather than proxying.
Note
This is not a question on the difference between spring AOP and aspect J, this is well articulated here:
Spring AOP vs AspectJ
#Aspect is not a spring annotation, and it is not detected by component-scan. So you have to register it somehow as a spring bean. The aspectOf solution works. You can also try
#Aspect
#Component
#Component will create 2 instances, one inside the Spring container, one inside the aspectJ container.
use #Configurable to allow spring to manage dependency injection etc. for your class when instantiated by the aspectj container.
#Aspect is an aspectj style annotation that is supported by spring-aop, where runtime weaving is used to handle interception etc.
Compile-time weaving allows you to disregard the use of as pointcuts will be present in the bytecode, this is done via the aspectj compiler (See https://www.mojohaus.org/aspectj-maven-plugin/ for mvn integration) .
Whether you use the aspectj compiler or spring-aop makes no difference, it wont create your aspect as a managed bean in the way you want unless you use factory / configurable.
Aspectj configuration is, strictly, the pointcut definitions etc that will be present inside your class.

Using both RolesAllowed and Transactional in beans

I have some beans which contain methods which are annotated with both #RolesAllowed and #Transactional. I have one Spring config file which utilizes a BeanNameAutoProxyCreator for Security related beans and another Spring config file which utilizes a BeanNameAutoProxyCreator for Transactional related beans.
The problem is that some beans contain both security as well as transactional-related beans. So Spring creates proxies for one set of beans. It then tries to create proxies for the other set of beans. When it does, it tries to create proxies of the proxies and bombs out.
Has anyone tried to configure both security and transactionality in the same beans via Spring? What's the trick?
Thanks.
I've never tried it, buy I would look to use one BeanNameAutoProxyCreator that works on both annotation? This BeanNameAutoProxyCreator can create a proxy that delegates to the security and transactional proxies.

Something like EJB wiring in Spring for non EJB's

I've noticed recently that spring can wire up my ejb's for me if I annotate the ejb with #Interceptors(SpringBeanAutowiringInterceptor.class). I've never actually done this so don't know the details.
I was wondering, is there a way to get this to work with other kinds of beans, for example, #WebService annotated ones as well.
At the moment in my web service classes (because the application server manages them) I have to load the dependencies from the BeanFactory and would thus prefer to have them autowired.
I know I could use the #Configurable annotation but am not particularly keen to have to specify and agent on the VM.
Is this possible?
Once again, spring has thought of this use case and catered for it!
The problem is that #WebService is not a spring annotation, it is a JAX-WS annotation and thus classes that are annotated with #WebService to be exposed as web services are not managed by spring, but their life cycle is managed by JAX-WS.
The way to handle this case is to have the JAX-WS managed bean extend org.springframework.web.context.support.SpringBeanAutowiringSupport - this will enable the #Autowire annotation, for example, to work in this bean. see here for more information
Yes, of course. There's #WebService, #Repository, #Controller, #Service, #Endpoint, and other annotations in Spring. Here's an example.

Categories