I have an abstract class and two sub classes that extend it. I have the following in spring config file
<bean id="importConfigFile" class="xxx.ImportConfigFiles" parent="parentImportFile"></bean>
<bean id="importFile" class="xxx.ImportUMTSKPIFiles" parent="parentImportFile"></bean>
<bean id="parentImportFile" name="parentImportFile" class="xxx.ImportUMTSFiles" abstract="true"></bean>
<tx:annotation-driven transaction-manager="transactionManager" />
In my abstract class I have the following methods
public void importDataToDB(){
//all the good stuff goes in here
}
@Transactional
public void executeInsertUpdateQuery(){
//all the good stuff goes in here
}
My java code
ImportConfigFiles importConfigFiles = (ImportConfigFiles)context.getBean("importConfigFile");
importConfigFiles.setFileLocation(destPath);
importConfigFiles.importDataToDB();
This does not work. executeInsertUpdateQuery() executes just one native sql query. If I put @Transactional on imortDataToDB() it works but then it makes my transaction huge since inside that method I loop through all the rows in a file and insert the records in db.
This is one of the major pitfalls in Spring – if you call
@Transactional-method from non-transactional method in the same class, the@Transactionalis ignored (unless you use AspectJ weaving). This is not Spring problem per se – the EJB has the same shortcomings.Unfortunately with interface-based and class-based proxies all you can do is to split your class in two:
The whole hustle is caused by the internal implementation of AOP proxies in Spring. With the code above new transaction will be started every time you call
b.executeInsertUpdateQuery()from non-transactionalBeanA.I wrote about it on my blog Spring pitfalls: proxying, Spring AOP riddle and Spring AOP riddle demystified.