turgayz
08-16-2004, 06:54 AM
Hi,
The question is: What is the simplest way to define declarative transaction demarcation for all my Struts actions?
If I try to explain further:
Our project currently uses Struts and Castor. We want to move to Spring and Hibernate (with Struts still present for the moment).
The architecture we came up with is like this (giving example class names):
OfferDAO (interface)
OfferDAOHibernate (implements OfferDAO)
OfferManager (interface)
OfferManagerImpl (implements OfferManager) (calls methods of OfferDAO)
These are all set up now. Relevant parts in the applicationContext.xml looks like this:
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="offerDAO" class="dao.hibernate.OfferDAOHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="offerManager"
class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="offerManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
<bean id="offerManagerTarget"
class="offer.OfferManagerImpl">
<property name="offerDAO"><ref local="offerDAO"/></property>
</bean>
I have written unit tests and it works beautifully. However, all the methods in the managers are the methods present in the DAOs... Which means that the managers are not real managers at the moment, but a facade to call the DAO methods instead.
Now I want to adapt my Struts actions to use this setup. Unfortunately, at the moment in our Struts actions, what we do is this:
1. Get a transaction context, and begin transaction
2. Get necessary parameters from request object
3. Do lots of business logic
4. At the end, commit or rollback the transaction.
With the new Struts+Hibernate setup, I understand that I have to move lots of the code in my Struts actions to the Managers... As an example, we have a "CreateOfferAction" Struts action. I already refactored it to call the methods from OfferManager, which in turn calls methods of OfferDAO. However, since I defined declarative transactions for the OfferManager, each call from the Struts action takes its own transaction. But of course what I want is, that in a single Struts action, all calls to the OfferManager methods to share a single transaction.
So, let me repeat the question again: I have lots of Struts actions, which obviously have their own "execute" methods. How can I define in the applicationContext.xml file so that all "execute" methods of all Struts actions to have "PROPAGATION_REQUIRED" declarative transaction?
To illustrate, I want to have:
<for all classes that extend from a particular class (org.apache.struts.action.Action here)>
<property name="transactionAttributes">
<props>
<prop key="execute*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</for all>
Of course, ideally, I'll refactor the actions to call the managers only, sending request parameters, and accepting parameters to be put into the response object. All transactons will take place in the manager methods. But at the moment, I don't have that time, so I'd like to learn if there is any simple way to make all "execute" methods of Struts actions to have their own transactions, using Spring AOP support...
Thanks in advance,
Regards,
Turgay Zengin
The question is: What is the simplest way to define declarative transaction demarcation for all my Struts actions?
If I try to explain further:
Our project currently uses Struts and Castor. We want to move to Spring and Hibernate (with Struts still present for the moment).
The architecture we came up with is like this (giving example class names):
OfferDAO (interface)
OfferDAOHibernate (implements OfferDAO)
OfferManager (interface)
OfferManagerImpl (implements OfferManager) (calls methods of OfferDAO)
These are all set up now. Relevant parts in the applicationContext.xml looks like this:
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="offerDAO" class="dao.hibernate.OfferDAOHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="offerManager"
class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="offerManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
<bean id="offerManagerTarget"
class="offer.OfferManagerImpl">
<property name="offerDAO"><ref local="offerDAO"/></property>
</bean>
I have written unit tests and it works beautifully. However, all the methods in the managers are the methods present in the DAOs... Which means that the managers are not real managers at the moment, but a facade to call the DAO methods instead.
Now I want to adapt my Struts actions to use this setup. Unfortunately, at the moment in our Struts actions, what we do is this:
1. Get a transaction context, and begin transaction
2. Get necessary parameters from request object
3. Do lots of business logic
4. At the end, commit or rollback the transaction.
With the new Struts+Hibernate setup, I understand that I have to move lots of the code in my Struts actions to the Managers... As an example, we have a "CreateOfferAction" Struts action. I already refactored it to call the methods from OfferManager, which in turn calls methods of OfferDAO. However, since I defined declarative transactions for the OfferManager, each call from the Struts action takes its own transaction. But of course what I want is, that in a single Struts action, all calls to the OfferManager methods to share a single transaction.
So, let me repeat the question again: I have lots of Struts actions, which obviously have their own "execute" methods. How can I define in the applicationContext.xml file so that all "execute" methods of all Struts actions to have "PROPAGATION_REQUIRED" declarative transaction?
To illustrate, I want to have:
<for all classes that extend from a particular class (org.apache.struts.action.Action here)>
<property name="transactionAttributes">
<props>
<prop key="execute*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</for all>
Of course, ideally, I'll refactor the actions to call the managers only, sending request parameters, and accepting parameters to be put into the response object. All transactons will take place in the manager methods. But at the moment, I don't have that time, so I'd like to learn if there is any simple way to make all "execute" methods of Struts actions to have their own transactions, using Spring AOP support...
Thanks in advance,
Regards,
Turgay Zengin