Object Manager has been closed org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed at org.datanucleus.ObjectManagerImpl.assertIsOpen(ObjectManagerImpl.java:3876) at org.datanucleus.ObjectManagerImpl.getFetchPlan(ObjectManagerImpl.java:376) at org.datanucleus.store.query.Query.getFetchPlan(Query.java:497) at org.datanucleus.store.appengine.query.DatastoreQuery$5.apply(DatastoreQuery.java:508) at org.datanucleus.store.appengine.query.DatastoreQuery$5.apply(DatastoreQuery.java:507) at org.datanucleus.store.appengine.query.StreamingQueryResult.resolveNext(StreamingQueryResult.java:137) at org.datanucleus.store.appengine.query.StreamingQueryResult$1.computeNext(StreamingQueryResult.java:163) at org.datanucleus.store.appengine.query.AbstractIterator.tryToComputeNext(AbstractIterator.java:132) at org.datanucleus.store.appengine.query.AbstractIterator.hasNext(AbstractIterator.java:127) at org.datanucleus.store.appengine.query.StreamingQueryResult$AbstractListIterator.hasNext(StreamingQueryResult.java:229) at jp.co.tricell.sonicboom.rpc.test.TestMutterUtils.testGetMutterOf(TestMutterUtils.java:44) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at junit.framework.TestCase.runTest(TestCase.java:164) at junit.framework.TestCase.runBare(TestCase.java:130) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:120) at junit.framework.TestSuite.runTest(TestSuite.java:230) at junit.framework.TestSuite.run(TestSuite.java:225) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)むぅーと思っていたら、ひがさんのブログでちょうど参考になる記事発見。
参考:JDOのモデルの状態を理解しよう - ひがやすを blog
テスト元メソッドは以下。つまりPersistenceManagerをclose()したのに、テストケースの方でクエリの結果を触ろうとしていたので「Object Manager has been closed」が出たということ。
// クラスのアノテーションを記述 @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Mutter { ・・・・・ } public class MutterUtils { ・・・・・ public List<Mutter> getMutterOf(String myKey) { PersistenceManager pm = PMF.get().getPersistenceManager(); Query query = pm.newQuery(Mutter.class); query.declareParameters("String myKey"); query.setFilter("userName == myKey"); query.setOrdering("date DESC"); List<Mutter> mutters = (List<Mutter>) query.execute(myKey); pm.close(); return mutters; } }ひがさんの記事を参考に、クラスのアノテーションに太字部分を追加。
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")。
これでPersistenceManagerをclose()した後でも触れるdetachedなモデルになった。
さらに、PersistenceManager#detachCopy()やPersistenceManager#detachCopyAll()を呼ぶのが面倒なので、jdoconfig.xmlに以下のpropertyタグを追加。
<property name="datanucleus.DetachOnClose" value="true"/>
あわせて、JDOのモデルには以下の4パターン
- transient
- persistent
- detached
- hollow
0 件のコメント:
コメントを投稿