#Transactional in the controller - java

First of all I want to mention that I fully agree to only make the service layer transactional, but sometimes world is not perfect, and right now I´m in the middle of that situation.
Basically I have been assigned into a wonderful project with a legacy code of 4+ years. The thing is that the developers did not follow any pattern where to introduce the bussines logic so you can image multiples services call from the controller and after that some extra call to private method into the controller.
No budget to refactor, and we have many issues with ACID so the only solution that I found is make the controllers transactional and at least then have a full rollback if something in the middle of the request/response go wrong.
The problem is that I cannot make it works. I will describe you my configuration to see if you can help me out guys.
I have a DispatcherServlet that invoke webmvc-config.xml where I have the declaration of the controllers
<context:component-scan base-package="com.greenvalley.etendering.web.controller**" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
Then the contextConfiguration invoke my applicationContext.xml where I have all the rest of my Spring configuration.
After read so many tickets I tried many convination, for example try to declare again my controllers into the application context.
<tx:annotation-driven mode="aspectj"/> I tried with proxy as well
<context:component-scan base-package="com.greenvalley.etendering.web.controller.*" />
But still nothing.
In the configuration of my txManager I dont do nothing fancy, just add the reference to the entityManagerFactory and that´s it
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
In my controller I add the #Transactional, but nothing every time that I made a request to the #transactional class/method I dont see that the breakpoint into JpaTransactionalManager doBegin method stop
any suggestion please!
Regards

Related

Understanding spring proxying

The Spring documentation provides the following example to show us the reason why we need to define aop:scoped-proxy explicitly in beans of scope session, reques, etc.
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
We need proxy here, because for each request to the userPreferences bean we want to delegate one to the actual session-scoped bean's instance. That's clear. But the documentation also said that this's a deafult behavior for singletone/prototype scoped beans.
Consider the following example:
<bean id="userPreferences" class="com.foo.UserPreferences" />
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Why do we need in proxy in the case of singletone-scoped beans? Doesn't injecting and calling to proxy cause some performance overhead?
Question: For performance sakes, could we avoid injecting proxy and inject actual bean instances in the case of the singletone-scoped beans instead?

Nesting abstract beans in Spring and init-method does not seem to work

I have the following construct Spring XML (Spring 3.1):
<bean id="taskRunner" abstract="true" init-method="startThreads"
class="my.class.TaskRunner" />
...
<bean id="taskRunnerA" parent="taskRunner">
<constructor-arg name="foo">...</constructor-arg>
<property name="bar">...</property>
</bean>
And I am trying to separate out the init method into a higher level abstract bean:
<bean id="taskRunnerLauncher" abstract="true" init-method="startThreads" />
<bean id="taskRunner" abstract="true" depends-on="taskRunnerLauncher"
class="my.class.TaskRunner" />
...
<bean id="taskRunnerA" parent="taskRunner">
<constructor-arg name="foo">...</constructor-arg>
<property name="bar">...</property>
</bean>
Somehow this does not work, i.e. startThreads() is never invoked in the second case. Does anybody know why? Does Spring support nested abstract beans?
My idea for doing this is so I can override "taskRunnerLauncher" in unit tests and set it to "mock" or "java.lang.Object" and suppress startThreads() call (which starts new thread and making it a pain to test).
Does anybody know why?
The taskRunnerLauncher bean is set to be abstract. This means it will only act as a template for other beans. Spring will not actually create a bean for it. Therefore there won't be any invocation of startThreads because there is nothing to invoke it on.
Found the problem. I mistakenly used depends-on instead of parent attribute on taskRunner bean.

Spring Beans: Scan for Converters, Inject into CustomConversionServiceFactory

I've got a MyAppConversionServiceFactoryBean which I'm registering like:
<bean id="conversionService" class="com.MyProject.MyAppConversionServiceFactoryBean">
<property name="messageSource" ref="messageSource"/>
<property name="converters">
<set>
<bean class="com.MyProject.XRepresentationConverter" />
<bean class="com.MyProject.YRepresentationConverter" />
<bean class="com.MyProject.ZRepresentationConverter" />
</set>
</property>
</bean>
I can continue to list every converter we write into this list, but I'd love to be able to configure it such that this isn't necessary and that converters will automatically register themselves somehow with my factory.
Sidebar 1: If that's not possible with a custom factory, is it possible with the default spring one?
Sidebar 2: If neither the first part nor Sidebar 1 is possible, is it possible to #Autowired the conversionService into the converters (so they can easily call one another)? Attempting to #Autowired ConversionService conversionService has previously given me issues due to not being able to wire the conversionService into an object while it's still busy creating the service.
Note: We're using Spring, but not Spring MVC. I have no control over that, so any solutions on that route will be unfortunately unusable. I can change pretty much anything else about the configuration and Java classes, just not the overarching tools.
#Vikdor's comment on the question pointed me in the right direction.
Spring is apparently capable (and no one I asked in person knew this) of gathering collections of beans through the scanning process with #Autowired annotations. Here's what I needed to achieve the same effect I got from the configuration in the post:
applicationContent.xml must have:
<context:component-scan base-package="com.MyProject"/>
<bean id="conversionService" class="com.MyProject.MyAppConversionServiceFactoryBean" />
MyAppConversionServiceFactoryBean.java:
public class MyAppConversionServiceFactoryBean implements
FactoryBean<ConversionService>, InitializingBean {
#Autowired
private Set<BaseConverter> converters;
}
And then all of my converters now have the #Component annotation.
Relevant Docs on #Autowired do briefly mention that it can be used to collect all beans of a type, but I wouldn't have known that it could be done into any collection type without this thread by Grzegorz Oledzki which addresses the generic form of my question, but takes it down a philosophical route.

Spring #transactional behaving strangely with mode=aspectj

I've been trying to get Spring transactions working properly in my application for days, and now I have nowhere to turn but to the community. Thanks in advance for your help.
My application has specific requirements where I need to annotate a protected overridden method with #Transactional and call this method from the abstract parent class. From what I've read, I can not use proxies, and must use mode=aspectj.
First, some configuration:
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="false" mode="aspectj" />
<context:load-time-weaver />
<bean name="ID_DataAccessor" class="dal.DataAccessor">
<constructor-arg ref="dataSource" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost" />
.....
<property name="defaultAutoCommit" value="true" />
</bean>
If I use the #Transactional annotation on a method in ID_DataAccessor, then the connection is transactional (DataSourceUtils.isConnectionTransactional(c, dataSource) == true). This is useless to me though, because the transaction commits as soon as the method is completed. When I use #Trasnactional on a method that calls a method in DataAccessor, the connection aquired in DataAccessor (from DataSourceUtils.getConnection(dataSource)) is NOT transactional. Additionally, I put a breakpoint in DataSourceTransactionManager.doGetTransaction(), and this is only called if the #Transactional annotation is directly on the method acquiring the connection. Forgive me for overloading the terminology, but it appears that the #Transactional annotation does not propagate up the stack.
I'm completely baffled. Please help! :)
I just about gave up on this one. It was quite non-obvious. Your problem is caused by using the EndOfDayProcess class in your entry point. It's a problem because it causes the class to be loaded, and more generally, it'll extend to any of your *Process and *EntryPoint classes. At that point in your code, Spring hasn't been started yet, so its load-time weaver isn't active, and the class gets loaded normally, without the transaction code woven into it. Of course, classes are only loaded once, so it's there to stay, and when you create the bean in Spring, it's a bean whose type doesn't have anything to do with transactions, except it has #Transactional annotations on it. By then, there's nobody there to see them anymore, though. I see two possible (good) solutions:
Switch to build-time weaving. Then it's impossible to load a class before it's woven.
Change the way you determine which *Process bean to use based on the entry point. Use anything you like except for something that causes the *Process class to be loaded.

Spring MVC: disable DefaultAnnotationHandlerMapping

I'm using Spring MVC with <mvc:annotation-driven />
I've implemented my own mapping handler extending DefaultAnnotationHandlerMapping, but I'm not sure how to use it. I've declared it like this:
<bean class="es.kcsolutions.boulevard.DispatcherMappingHandler" />
It works, but, obviously, DefaultAnnotationHandlerMapping works too and always before mine. Is there a way to disable it and use only mine?
Thanks.
My advice would be to remove the <mvc:annotation-driven /> altogether. It doesn't really do anything particularly useful - most of the beans it declares are there already. And in cases where you want to declare your own handler mapping or handler adapter, it just gets in the way.
So take it out, declare your own DefaultAnnotationHandlerMapping bean, and it should work. No need to mess about with ordering in 99.9% of cases.
If you take out any explicit declarations of the DefaultAnnotationHandlerMapping then your custom mapper is supposed to replace it in the dispatcher. (according to javadoc) If you need/want more than one mapping, then you control them by setting their Order property. Lower order numbers execute first.
<bean class="es.kcsolutions.boulevard.DispatcherMappingHandler">
<property name="order" value="0"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="1"/>
</bean>

Categories

Resources