2012-01-13 16 views
7

Solía ​​tener todos mis DAO ampliar la clase JdoDaoSupport que ahora es deprecated in Spring 3.1. He hecho mi propia clase AbstractJdoDao que envuelve el PersistenceManagerFactory y todos los DAO se extienden desde allí. ¿Es esa la forma en que debería estar haciendo?Configurando JDO en Spring 3.1?

También en el documentation on JDO, parece que la instanciación directa de PersistenceManagerFactory no es la opción por defecto, sino utilizar LocalPersistenceManagerFactoryBean envuelto en una TransactionAwarePersistenceManagerFactoryProxy. Cómo crear una instancia adecuada de estos beans y hacerlos funcionar con las anotaciones de Spring @Transactional.

Aquí es la parte relacionada con la persistencia de mi contexto de aplicación:

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

Ahora, cuando me carga una página de acceso al almacén de datos:

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 

Tengo my example project on GitHub. Está utilizando Google App Engine, por lo tanto, ejecútelo a través de mvn gae:run en Eclipse (con el complemento de Google para Eclipse), creando primero un proyecto de Eclipse a través del mvn eclipse:eclipse.

+0

Al leer la documentación, concluyo que la propiedad "persistenceManagerFactory" del bean "transactionManager" debe hacer referencia al bean "LocalPersistenceManagerFactoryBean" en lugar del proxy. Entonces, debes darle a ese frijol una identificación, en lugar de ser anónimo como en tu ejemplo. – Luciano

Respuesta

3

Mi sugerencia sería utilizar TransactionAwarePersistenceManagerFactoryProxy o SpringPersistenceManagerProxyBean según lo sugerido por la documentación de Spring 3.1. Parece que esto está diseñado para reemplazar la clase JdoDaoSupport.

Si bien lo que estás sugiriendo en su cuestión de la creación de su propia AbstractJdoDao envoltorio, por supuesto, eliminar la advertencia desaprobación, mi única preocupación es que puede crear una situación sin darse cuenta de que es difícil para los demás a mantener, ya que no será a lo que están acostumbrados a ver.

Por otro lado, imagino la creación de su propio envoltorio es una manera muy rápida para resolver su problema ...

Usted debe sopesar cuidadosamente las ventajas/desventajas de la utilización de su propio envoltorio con las ventajas/desventajas de seguir adelante con la forma de hacer las cosas de Spring 3.1. En mi experiencia, tomar atajos puede, a menudo, volver a perseguirte en el futuro.

+0

¿Debería el 'AbstractJdoDao' tener más bien una referencia a' TransactionAwarePersistenceManagerFactoryProxy' que 'PersistenceManagerFactory'? – hleinone

+0

Sí, tienes razón. Los ejemplos que están usando en [la documentación de Spring 3.1 JDO] (http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/orm.html#orm-jdo -daos-straight) muestra el PersistenceManagerFactory inyectado en su clase Dao utilizando un objeto TransactionAwarePersistenceManagerFactoryProxy. Supongo que podrías inyectar eso en una clase abstracta y heredar de ella lo mismo; sin embargo, no están usando una clase abstracta en los ejemplos. De acuerdo con los documentos, la ventaja de este método es que no está utilizando ninguna dependencia de Spring. – jmort253

+0

He aislado el problema en un [proyecto en GitHub] (https://github.com/hleinone/spring-gae-jdo). Todavía terminando con la misma excepción. – hleinone