I've come up with a solution to my problems with data store integration tests. I don't know if this is a good solution; feedback is welcome.
The problem, as much as my feeble brain can grasp, is that when Spring provides you with a PersistenceManager, you need to use transactions so that, at the appropriate time, the PersistenceManager's close() is called (by Spring). I'm assuming that in the previous, when I say transactions, I mean Spring's transactions; in my case Spring's @Transactional annotation. When I say "Spring provides you with a PersistenceManager", in my case this means my DAO is subclassing JdoDaoSupport. If you don't have any transactions in your test code (including your DAO) I don't know when or if the PersistenceManager's close() is called. But you'll get errors about objects being managed by a different PersistenceManager so this doesn't seem to be an option. You'll also get errors with objects that had detachCopy() applied to them before they were returned. Some people use transactions in their DAOs. My understanding is that the transactions should be in the coarse grained methods (the service layer) and not in the fine grained methods (the DAO layer). If this doesn't sound right, have a look at the pdf available from http://apress.com/book/downloadfile/2625 Whether or not you could have your DAOs using transactions as well as your service layer classes, I don't know. If you use Spring's @Transactional annotation on your unit test's methods, that may work, but it won't if you're using a @Before method to add stuff to the data store to test with, which is what was biting me. At first I started thinking that I'd have to give up testing my DAOs and only test my service layer classes since they use @Transactional. But then it occurred to me that I could sort of achieve the same thing by wrapping all of my DAO methods in transactions *but only during testing*. So far this seems to work. My test class starts out as follows: @RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class }) @ContextConfiguration(locations = { "classpath:spring/applicationContext.xml", "classpath:spring/jdo-gae-context.xml", "classpath:jdo-tx-test-context.xml" }) public class FacilityDaoTest extends LocalDatastoreTestCase { private final transient Logger log = LoggerFactory.getLogger(getClass()); private final String facilityName = "abc"; @Autowired @Qualifier("jdo") private IFacilityDao facilityDao; final Facility[] facilities = new Facility[] { new Facility("Abc Facility", this.facilityName, false), new Facility("Def Facility", this.facilityName + "-2", true), new Facility("ghi Facility", this.facilityName + "-3", true), }; @Before public void insertFacilities() throws Exception { Assert.assertEquals(0, DatastoreServiceFactory .getDatastoreService() .prepare(new Query(Facility.class.getSimpleName())) .countEntities()); for (final Facility eachFacility : this.facilities) { this.facilityDao.makePersistent(eachFacility); this.log.debug("facility: {}", eachFacility); } Assert.assertEquals(this.facilities.length, DatastoreServiceFactory .getDatastoreService() .prepare(new Query(Facility.class.getSimpleName())) .countEntities()); } @Test public void findByName() { final Facility facility = this.facilityDao.findByName(this.facilityName); Assert.assertNotNull("facility should not be null", facility); } applicationContext.xml contains <context:annotation-config /> <context:component-scan base-package="com.objecteffects.waitlist" /> jdo-gae-context.xml contains <tx:annotation-driven transaction-manager="transactionManager" /> <beans:bean id="dataNucleusJdoDialect" class="org.datanucleus.springframework.DataNucleusJdoDialect" /> <beans:bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager"> <beans:property name="persistenceManagerFactory" ref="persistenceManagerFactory" /> <beans:property name="jdoDialect" ref="dataNucleusJdoDialect" /> </beans:bean> <beans:bean id="persistenceManagerFactory" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean"> <beans:property name="persistenceManagerFactoryName" value="transactions-optional" /> </beans:bean> And the "trick" is jdo-tx-test-context.xml, which creates an aop proxy to wrap the dao methods, and it contains <tx:advice id="transactionAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="waitlistServiceOperation" expression="execution(* com.objecteffects.waitlist.db.impl.dao.jdo.*.*(..))" /> <aop:advisor advice-ref="transactionAdvice" pointcut-ref="waitlistServiceOperation" /> </aop:config> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-java@googlegroups.com To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en -~----------~----~----~----~------~----~------~--~---