PDA

View Full Version : Transaction, AOP and my own aspects



MmarcoM
Feb 17th, 2005, 04:06 PM
hi all,
i have written a PersistenceManager component that uses HibernateDAOSupport to interact with the database.
Following some examples on a tutorial, i have declared transaction in applicationContext.xml, like following

<code>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
- Application context definition for JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
-->
<beans>

<!-- ========================= GENERAL DEFINITIONS ========================= -->



<!-- Configurer that replaces ${...} placeholders with values from properties files -->
<!-- (in this case, mail and JDBC related properties) -->

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerD ataSource">

<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/menagerie?autoReconnect=true</value>
</property>

<property name="username">
<value>root</value>
</property>
<property name="password">
<value>mypass</value>
</property>
</bean>

<bean id="stockDataSource"
class="org.springframework.jdbc.datasource.DriverManagerD ataSource">

<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/informa?autoReconnect=true</value>
</property>

<property name="username">
<value>root</value>
</property>
<property name="password">
<value>mypass</value>
</property>
</bean>


<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="mappingResources">
<list>
<value>com/myapp/hibernate/HibernateEntry.hbm.xml</value>
<value>com/myapp/hibernate/HibernateExpenseType.hbm.xml</value>
<value>com/myapp/hibernate/HibernateUser.hbm.xml</value>
<value>com/myapp/hibernate/HibernateStock.hbm.xml</value>

</list>
</property>
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

<bean id="stockSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="mappingResources">
<list>
<value>de/informa/impl/hibernate/Items.hbm.xml</value>

</list>
</property>
<property name="dataSource">
<ref local="stockDataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>


<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>


<!-- Persistence Layer -->

<bean id="persistenceManager"
class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">

<property name="proxyInterfaces">
<value>com.myapp.common.PersistenceManager</value>
</property>
<property name="target">
<ref local="persistenceManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>

<property name="interceptorNames">
<list>
<value>beforeAdvisor</value>
<value>afterAdvisor</value>
<value>queryAdvisor</value>
</list>
</property>
</bean>



<bean id="persistenceManagerTarget" class="com.myapp.common.PersistenceManagerImpl">
<property name="budgetDAO">
<ref local="budgetDAO"/>
</property>
</bean>



<bean id="stockPersistenceManager" class="com.myapp.common.StockPersistenceManagerImpl">
<property name="stockDAO">
<ref local="stockDAO"/>
</property>
</bean>


<bean id="budgetDAO" class="com.myapp.hibernate.HibernateDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

<bean id="stockDAO" class="com.myapp.hibernate.HibernateStockDAOImpl">
<property name="sessionFactory">
<ref local="stockSessionFactory"/>
</property>
</bean>

<!-- Web Layer -->

<bean name="/logon" class="com.myapp.action.LoginAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
</bean>

<bean name="/insert" class="com.myapp.action.InsertAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
</bean>

<bean name="/delete" class="com.myapp.action.DeleteAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
</bean>


<bean name="/modify" class="com.myapp.action.ModifyAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
</bean>

<bean name="/query" class="com.myapp.action.QueryAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
</bean>

<bean name="/schedule" class="com.myapp.action.SchedulerAction"
singleton="false">
<property name="persistenceManager">
<ref bean="persistenceManager"/>
</property>
<property name="scheduler">
<ref bean="scheduler"/>
</property>
</bean>


<bean name="/scheduleSetUp" class="com.myapp.action.SchedulerSetUpAction"
singleton="false">
<property name="scheduler">
<ref bean="scheduler"/>
</property>
</bean>

<bean name="/stock" class="com.myapp.action.StockNewsAction"
singleton="false">
<property name="stockPersistenceManager">
<ref bean="stockPersistenceManager"/>
</property>
</bean>


<!-- Scheduler Layer -->


<bean id="springScheduler" class="org.springframework.scheduling.quartz.SchedulerFac toryBean">
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>

<bean name="budgetJob" class="org.springframework.scheduling.quartz.JobDetailBea n">
<property name="jobClass">
<value>com.myapp.scheduler.BudgetJob</value>
</property>
</bean>

<bean name="scheduler" class="com.myapp.scheduler.WorldCorpScheduler">
<property name="budgetJob">
<ref bean="budgetJob"/>
</property>
<property name="scheduler">
<ref bean="springScheduler"/>
</property>
</bean>


<!-- AOP -->
<bean id="beforeAdvice" class="com.myapp.aop.TracingBeforeAdvice"/>
<bean id="afterAdvice" class="com.myapp.aop.TracingAfterAdvice"/>
<bean id="insertAdvice" class="com.myapp.aop.InsertBeforeAdvice"/>

<bean id="beforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointc utAdvisor">
<property name="advice">
<ref local="beforeAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<bean id="afterAdvisor"
class="org.springframework.aop.support.RegexpMethodPointc utAdvisor">
<property name="advice">
<ref local="afterAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>

<bean id="queryAdvisor"
class="org.springframework.aop.support.RegexpMethodPointc utAdvisor">
<property name="advice">
<ref local="insertAdvice"/>
</property>
<property name="pattern">
<value>com.myapp.common.PersistenceManager.insert*</value>
</property>
</bean>

</beans>
</code>

so i have declared my PersistenceManager as a TransactionProxyFactoryBean.
the problem is that i have also written my own advisors to be applied to persistenceManager, and i am receiving the following exception when my application is started:

2005-02-17 21:59:04,515 ERROR [org.jboss.web.localhost.Engine] StandardContext[/budget-web]StrutsActionServlet: null
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'persistenceManager' defined in resource [/WEB-INF/applicationContext.xml] of ServletContext: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'interceptorNames' of bean class [org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean]: Property 'interceptorNames' is not writable
org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'interceptorNames' of bean class [org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean]: Property 'interceptorNames' is not writable


Question is: how can i declare interceptorNames and
transactionAttributes on the same bean? which type of class will it be?

thanx in advance and regards
marco

katentim
Feb 18th, 2005, 09:38 PM
Try:

<property name="preInterceptors">
<list>
<ref local="beforeAdvisor"/>
<ref local="queryAdvisor"/>
</list>
</property>
<property name="postInterceptors">
<list>
<ref local="afterAdvisor"/>
</list>
</property>

Take a look at the API for TransactionProxyFactoryBean (http://www.springframework.org/docs/api/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.html). You can see what properties can be set there and in its superclasses