|
#1
|
|||
|
|||
|
I'm trying to migrate from the old 1.2.x style to the 2.0 XSD style. Here's what I have in 1.2.8:
Code:
<!-- Transaction template for Managers, from:
http://blog.exis.com/colin/archives/2004/07/31/concise-transaction-definitions-spring-11/ -->
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- Generic manager that can be used to do basic CRUD operations on any objects -->
<bean id="manager" parent="txProxyTemplate">
<property name="target">
<bean class="org.appfuse.service.impl.BaseManager">
<property name="dao" ref="dao"/>
</bean>
</property>
</bean>
<!-- Transaction declarations for business services. To apply a generic transaction proxy to
all managers, you might look into using the BeanNameAutoProxyCreator -->
<bean id="userManager" parent="txProxyTemplate">
<property name="target">
<bean class="org.appfuse.service.impl.UserManagerImpl">
<property name="userDao" ref="userDao"/>
</bean>
</property>
<!-- Override default transaction attributes b/c of UserExistsException -->
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED,-UserExistsException</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
<!-- This property is overriden in applicationContext-security.xml to add
method-level role security -->
<property name="preInterceptors">
<list>
<ref bean="userSecurityInterceptor"/>
</list>
</property>
</bean>
<!-- This interceptor insures that that users can only update themselves, not other users -->
<bean id="userSecurityInterceptor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="userSecurityAdvice"/>
<property name="patterns" value=".*saveUser"/>
</bean>
<bean id="userSecurityAdvice" class="org.appfuse.service.UserSecurityAdvice">
<property name="userCache" ref="userCache"/>
</bean>
Code:
<aop:config>
<aop:advisor id="serviceMethods" pointcut="execution(* *.service.*Manager.*(..))" advice-ref="txAdvice"/>
<aop:advisor id="userManagerMethods" pointcut="execution(* *.service.UserManager.*(..))"
advice-ref="userManagerTxAdvice"/>
<aop:advisor id="userManagerSecurity" pointcut="execution(* *.service.UserManager.saveUser(..))"
advice-ref="userSecurityAdvice"/>
</aop:config>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<tx:advice id="userManagerTxAdvice">
<tx:attributes>
<tx:method name="save*" rollback-for="UserExistsException"/>
<tx:method name="remove*"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- Generic manager that can be used to do basic CRUD operations on any objects -->
<bean id="manager" class="org.appfuse.service.impl.BaseManager">
<property name="dao" ref="dao"/>
</bean>
<bean id="userManager" class="org.appfuse.service.impl.UserManagerImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userSecurityAdvice" class="org.appfuse.service.UserSecurityAdvice">
<property name="userCache" ref="userCache"/>
</bean>
I thought removing the read-only flag from userManagerTxAdvice would work, but no dice, the issue still happens. Code:
<tx:advice id="userManagerTxAdvice">
<tx:attributes>
<tx:method name="save*" rollback-for="UserExistsException"/>
<tx:method name="remove*"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
Code:
[INFO] [talledLocalContainer] Caused by: javax.faces.el.EvaluationException: Exception while invokin
g expression #{signupForm.save}
[INFO] [talledLocalContainer] at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.
java:153)
[INFO] [talledLocalContainer] at org.apache.myfaces.application.ActionListenerImpl.processAction(A
ctionListenerImpl.java:63)
[INFO] [talledLocalContainer] ... 78 more
[INFO] [talledLocalContainer] Caused by: org.springframework.dao.InvalidDataAccessApiUsageException:
Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into Flush
Mode.AUTO or remove 'readOnly' marker from transaction definition
[INFO] [talledLocalContainer] at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOp
erationAllowed(HibernateTemplate.java:1082)
__________________
http://raibledesigns.com Last edited by mraible; Sep 1st, 2006 at 11:45 AM. |
|
#2
|
|||
|
|||
|
It might not be this simple but, have you tried changing your pointcuts to something a little more specific? It looks like all three pointcuts would match UserManager.saveUser joinpoint.
Code:
<aop:config>
<aop:advisor id="serviceMethods" pointcut="execution(* *.service.*Manager.*(..)) and !within(*.service.UserManager)" advice-ref="txAdvice"/>
<aop:advisor id="userManagerMethods" pointcut="within(*.service.UserManager)"
advice-ref="userManagerTxAdvice" order="2"/>
<aop:advisor id="userManagerSecurity" pointcut="execution(* *.service.UserManager.saveUser(..))"
advice-ref="userSecurityAdvice" order="1"/>
</aop:config>
|
|
#3
|
|||
|
|||
|
As far as I can tell, it appears that AspectJ's pointcut language does not support using wildcards (*) for package names. The following seems to work:
Code:
<aop:config>
<aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* org.appfuse.service.*Manager.*(..))"/>
<aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="within(org.appfuse.service.UserManager)"/>
<aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* org.appfuse.service.UserManager.saveUser(..))"/>
</aop:config>
__________________
http://raibledesigns.com |
|
#4
|
|||
|
|||
|
Try this:
http://www.eclipse.org/aspectj/doc/n...ePatterns.html I think "*" is for characters and ".." is for packages/sub-packages. Maybe an expression like this: Code:
execution(* *..*Manager.*(..))" Another way is to define a named pointcut outside the advisor and reference it with pointcut-ref. In that case you can choose a type of pointcut - aspectj or regex. Something like this: Code:
<aop:config> <aop:pointcut id="test" type="regex" expression="*.UserManager.saveUser"/> </aop:config> Dmitry |
|
#5
|
|||
|
|||
|
I tried the following, but no luck:
Code:
<aop:config>
<aop:pointcut id="serviceMethodsPointcut" type="regex" expression="*Manager.*"/>
<aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* org.appfuse.service.UserManager.*(..))" order="0"/>
<aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* org.appfuse.service.UserManager.saveUser(..))" order="1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethodsPointcut" order="2"/>
</aop:config>
Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'identifier' at character position 0 *Manager.* ^ The following works, but is missing the benefit of wrapping transactions around any beans with service.*Manager in their package/class name. Code:
<aop:config>
<aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* org.appfuse.service.UserManager.*(..))" order="0"/>
<aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* org.appfuse.service.UserManager.saveUser(..))" order="1"/>
<aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* org.appfuse.service..*Manager.*(..))" order="2"/>
</aop:config>
__________________
http://raibledesigns.com |
|
#6
|
|||
|
|||
|
Dmitry's suggestion of execution(* *..*Manager.*(..)) should really work.
Can you try the following: Code:
<aop:config>
<aop:pointcut id="serviceMethodsPointcut" expression="execution(* *..*Manager.*(..))"/>
<aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* org.appfuse.service.UserManager.*(..))" order="0"/>
<aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* org.appfuse.service.UserManager.saveUser(..))" order="1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethodsPointcut" order="2"/>
</aop:config>
__________________
Ramnivas Laddad (Follow me on Twitter) AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available! |
|
#7
|
|||
|
|||
|
If I use:
Code:
<aop:pointcut id="serviceMethodsPointcut" expression="execution(* *..*Manager.*(..))"/> Code:
[applicationContext-service.xml]: Invocation of init method failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.NullPointerException Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.NullPointerException Caused by: java.lang.NullPointerException at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:431) Code:
expression="execution(* *.service..*Manager.*(..))"
__________________
http://raibledesigns.com |
|
#8
|
|||
|
|||
|
You're welcome.
You probably need the following modification to your pointcut (simply move the '..' portion) Since it is working for you, I suspect you already have this or a similar change. Code:
expression="execution(* *..service.*Manager.*(..))" -Ramnivas
__________________
Ramnivas Laddad (Follow me on Twitter) AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available! |
![]() |
| Thread Tools | |
| Display Modes | |
|
|