Kiedyś wszystkie moje DAO rozszerzały klasę JdoDaoSupport
, która jest teraz deprecated in Spring 3.1. Zrobiłem własną klasę AbstractJdoDao
, która owija PersistenceManagerFactory
i wszystkie DAO rozszerzają się od tego miejsca. Czy tak powinienem robić?Konfigurowanie JDO na wiosnę 3.1?
Również w documentation on JDO, wydaje się, że bezpośrednie instancji od PersistenceManagerFactory
nie jest to opcja domyślna, ale używać LocalPersistenceManagerFactoryBean
zawinięte w TransactionAwarePersistenceManagerFactoryProxy
. Jak prawidłowo utworzyć te ziarna i sprawić, by działały z adnotacjami ze Springa @Transactional
.
Oto część związana wytrwałość-mojego kontekstu aplikacji:
<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>
Teraz gdy załadować stronę dostępu do magazynu danych:
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
ja mam my example project on GitHub. Korzysta z Google App Engine, więc uruchom go przez mvn gae:run
w Eclipse (z wtyczką Google for Eclipse), najpierw tworząc projekt Eclipse przez mvn eclipse:eclipse
.
Czytając dokumentację stwierdzam, że właściwość "persistenceManagerFactory" komponentu bean "transactionManager" powinna odwoływać się do komponentu bean "LocalPersistenceManagerFactoryBean" zamiast do proxy. Musisz nadać tej komórce identyfikator, zamiast być anonimowym, jak w twoim przykładzie. – Luciano