2012-01-13 58 views
7

我曾經讓我所有的DAO延伸JdoDaoSupport類,現在deprecated in Spring 3.1。我已經制作了我自己的AbstractJdoDao課程,它包裝了PersistenceManagerFactory,並且所有的DAO從那裏延伸。這是我應該怎麼做的方式?在Spring 3.1中配置JDO?

同樣在documentation on JDO中,似乎PersistenceManagerFactory的直接實例化不是默認選項,而是使用LocalPersistenceManagerFactoryBean包裝在TransactionAwarePersistenceManagerFactoryProxy中。如何正確實例化這些bean,並使它們與Spring的@Transactional註釋一起工作。

這裏是我的應用程序上下文的持久性相關的部分:

<bean id="persistenceManagerFactoryProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy"> 
    <property name="targetPersistenceManagerFactory"> 
     <bean class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean"> 
      <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。它使用的是Google App Engine,因此要麼通過Eclipse中的mvn gae:run(通過Google Plugin for Eclipse)運行它,首先通過mvn eclipse:eclipse創建一個Eclipse項目。

+0

閱讀文檔,我得出結論bean「transactionManager」屬性「persistenceManagerFactory」應該引用bean「LocalPersistenceManagerFactoryBean」而不是代理。所以你需要給這個bean一個id,而不是像你的例子那樣匿名。 – Luciano 2012-01-26 13:20:15

回答

3

我的建議是按照Spring 3.1文檔的建議使用TransactionAwarePersistenceManagerFactoryProxySpringPersistenceManagerProxyBean。看起來這是爲了取代JdoDaoSupport類而設計的。

雖然你在建立你自己的AbstractJdoDao包裝的問題上的建議當然會消除棄用警告,但我唯一擔心的是你可能無意中造成了難以維護的情況,因爲它不會是他們習慣看什麼。

在另一方面,我想創建自己的包裝是解決你的問題非常快速的方式...

你應該仔細權衡使用自己的包裝與優勢/劣勢的優勢/劣勢推動Spring 3.1的做事方式。根據我的經驗,採取捷徑可能而且往往會在未來困擾着你。

+0

那麼'AbstractJdoDao'應該比'PersistenceManagerFactory'有一個對'TransactionAwarePersistenceManagerFactoryProxy'的引用嗎? – hleinone 2012-01-28 16:42:24

+0

是的,你是對的。他們在[Spring 3.1 JDO文檔]中使用的示例(http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/orm.html#orm-jdo -daos-straight)顯示使用TransactionAwarePersistenceManagerFactoryProxy對象注入到您的Dao類中的PersistenceManagerFactory。我想你可以將它注入一個抽象類並繼承它,但是,他們在示例中沒有使用抽象類。根據文檔,這種方法的優點是你沒有使用任何Spring依賴。 – jmort253 2012-01-28 20:43:23

+0

我將問題隔離到[GitHub上的項目](https://github.com/hleinone/spring-gae-jdo)。仍然以幾乎相同的例外結束。 – hleinone 2012-01-30 15:28:11