我曾经让我的所有DAO扩展了JdoDaoSupport类,现在是
deprecated in Spring 3.1.我已经创建了自己的AbstractJdoDao类,它包装了PersistenceManagerFactory,并且所有DAO都从那里扩展.这是我应该做的方式吗?
同样在documentation on JDO中,似乎PersistenceManagerFactory的直接实例化不是默认选项,而是使用包装在TransactionAwarePersistenceManagerFactoryProxy中的LocalPersistenceManager@R_404_49@.如何正确实例化这些bean并使它们与Spring的@Transactional注释一起使用.
这是我的应用程序上下文中与持久性相关的部分:
<bean id="persistenceManagerFactoryProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy"> <property name="targetPersistenceManagerFactory"> <bean class="org.springframework.orm.jdo.LocalPersistenceManager@R_404_49@"> <property name="jdoPropertyMap"> <props> <prop key="javax.jdo.PersistenceManagerFactoryClass">org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory</prop> <prop key="javax.jdo.option.ConnectionURL">appengine</prop> <prop key="javax.jdo.option.NontransactionalRead">true</prop> <prop key="javax.jdo.option.NontransactionalWrite">false</prop> <prop key="javax.jdo.option.RetainValues">false</prop> <prop key="javax.jdo.option.DetachAllOnCommit">true</prop> <prop key="javax.jdo.option.Multithreaded">true</prop> <prop key="datanucleus.appengine.ignorableMetaDataBehavior">NONE</prop> </props> </property> </bean> </property> <property name="allowCreate" value="false" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager"> <property name="persistenceManagerFactory" ref="persistenceManagerFactoryProxy" /> </bean>
现在,当我加载访问数据存储的页面时:
org.springframework.transaction.CannotCreateTransactionException: Could not open JDO PersistenceManager for transaction; nested exception is java.lang.IllegalStateException: No JDO PersistenceManager bound to thread,and configuration does not allow creation of non-transactional one here at org.springframework.orm.jdo.JdoTransactionManager.doBegin(JdoTransactionManager.java:369) ~[spring-orm-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371) ~[spring-tx-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335) ~[spring-tx-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105) ~[spring-tx-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.1.0.RELEASE.jar:3.1.0.RELEASE] at $Proxy15.queryAll(Unknown Source) ~[na:na] ... Caused by: java.lang.IllegalStateException: No JDO PersistenceManager bound to thread,and configuration does not allow creation of non-transactional one here at org.springframework.orm.jdo.PersistenceManagerFactoryUtils.doGetPersistenceManager(PersistenceManagerFactoryUtils.java:153) ~[spring-orm-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy$PersistenceManagerFactoryInvocationHandler.invoke(TransactionAwarePersistenceManagerFactoryProxy.java:159) ~[spring-orm-3.1.0.RELEASE.jar:3.1.0.RELEASE] at $Proxy13.getPersistenceManager(Unknown Source) ~[na:na] at org.springframework.orm.jdo.JdoTransactionManager.doBegin(JdoTransactionManager.java:308) ~[spring-orm-3.1.0.RELEASE.jar:3.1.0.RELEASE] ... 73 common frames omitted
我有my example project on GitHub.它使用谷歌应用引擎,所以要么通过mvn gae运行:在Eclipse中运行(使用Google Plugin for Eclipse),首先通过mvn eclipse:eclipse创建一个Eclipse项目.
解决方法
我的建议是使用Spring 3.1文档中建议的TransactionAwarePersistenceManagerFactoryProxy或SpringPersistenceManagerProxyBean.看来这是为了取代JdoDaoSupport类.
虽然你在创建自己的AbstractJdoDao包装器的问题中提出的建议当然会消除弃用警告,但我唯一担心的是你可能会无意中创建一个其他人难以维护的情况,因为它不会被他们使用去看.
另一方面,我想创建自己的包装器是解决问题的一种非常快捷的方法……
您应该仔细权衡使用自己的包装器的优点/缺点以及使用Spring 3.1方式继续前进的优点/缺点.根据我的经验,走捷径可以并且经常会在将来再次困扰你.