2012-01-13 13 views
7

Avevo tutti i miei DAO estendere la classe JdoDaoSupport che ora è deprecated in Spring 3.1. Ho creato la mia classe AbstractJdoDao che include lo PersistenceManagerFactory e tutti i DAO si estendono da lì. È così che dovrei fare?Configurazione di JDO in primavera 3.1?

Anche nel documentation on JDO, sembra che l'istanza diretta di PersistenceManagerFactory non è l'opzione di default, ma di usare LocalPersistenceManagerFactoryBean avvolto in un TransactionAwarePersistenceManagerFactoryProxy. Come creare un'istanza appropriata di questi bean e farli funzionare con le annotazioni Spring @Transactional.

ecco la parte persistere correlata del mio contesto di applicazione:

<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> 

Ora quando carico una pagina accesso all'archivio dati:

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 

Ho my example project on GitHub. Utilizza Google App Engine, quindi eseguilo tramite mvn gae:run in Eclipse (con Google Plugin per Eclipse), creando prima un progetto Eclipse tramite mvn eclipse:eclipse.

+0

Leggendo la documentazione, concludo che la proprietà "persistenceManagerFactory" del bean "transactionManager" dovrebbe fare riferimento al bean "LocalPersistenceManagerFactoryBean" invece del proxy. Quindi devi dare a quel bean un id, invece di essere anonimo come nel tuo esempio. – Luciano

risposta

3

Il mio suggerimento sarebbe quello di utilizzare TransactionAwarePersistenceManagerFactoryProxy o SpringPersistenceManagerProxyBean come suggerito dalla documentazione Spring 3.1. Sembra che questo sia progettato per sostituire la classe JdoDaoSupport.

Mentre quello che stai suggerendo nella tua domanda di creare il tuo wrapper AbstractJdoDao ovviamente eliminerà l'avviso di deprecazione, la mia unica preoccupazione è che potresti inavvertitamente creare una situazione difficile da mantenere per gli altri in quanto non sarà quello che sono abituati a vedere.

D'altra parte, immagino creando il proprio involucro è un modo molto veloce per risolvere il tuo problema ...

Si dovrebbe valutare attentamente i vantaggi/svantaggi di usare il proprio involucro con i vantaggi/svantaggi di andare avanti con il modo di fare Spring 3.1. Nella mia esperienza, prendere scorciatoie può e spesso tornare a perseguitarti in futuro.

+0

Nel caso in cui 'AbstractJdoDao 'abbia un riferimento a' TransactionAwarePersistenceManagerFactoryProxy' rispetto a 'PersistenceManagerFactory'? – hleinone

+0

Sì, sei corretto. Gli esempi che stanno utilizzando nella [documentazione Spring JDO 3.1] (http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/orm.html#orm-jdo -daos-straight) mostra PersistenceManagerFactory iniettato nella classe Dao utilizzando un oggetto TransactionAwarePersistenceManagerFactoryProxy. Immagino che potresti iniettarlo in una classe astratta e ereditarlo ugualmente; tuttavia, non stanno usando una classe astratta negli esempi. Secondo i documenti, il vantaggio di questo metodo è che non stai usando alcuna dipendenza Spring. – jmort253

+0

Ho isolato il problema in un [progetto su GitHub] (https://github.com/hleinone/spring-gae-jdo). Ancora finendo con quasi la stessa eccezione. – hleinone