2

エンティティのリストを取得するために GAE データストアにクエリを実行しています (sdk 1.8.3 で dev gae を使用):

public List<OT> getAll() {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    Query q = pm.newQuery();
    q.setClass(OT.class);
    try {
        return (List<OT>) q.execute();
    }
    finally {
        q.closeAll();
        pm.close();
    }
}

これは常に行に投げてConcurrentModificationExceptionpm.close()ます:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
    at java.util.ArrayList$Itr.next(ArrayList.java:791)
    at com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection.close(DatastoreConnectionFactoryImpl.java:146)
    at org.datanucleus.store.connection.ConnectionManagerImpl.closeAllConnections(ConnectionManagerImpl.java:181)
    at org.datanucleus.store.AbstractStoreManager$1.preClose(AbstractStoreManager.java:260)
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1112)
    at org.datanucleus.api.jdo.JDOPersistenceManager.internalClose(JDOPersistenceManager.java:359)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.releasePersistenceManager(JDOPersistenceManagerFactory.java:1106)
    at org.datanucleus.api.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:343)

次の依存関係を使用しています。

    <dependency>
        <groupId>com.google.appengine.orm</groupId>
        <artifactId>datanucleus-appengine</artifactId>
        <version>2.0.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-core</artifactId>
        <version>3.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-api-jdo</artifactId>
        <version>3.1.3</version>
    </dependency>
    <dependency>
        <groupId>javax.jdo</groupId>
        <artifactId>jdo-api</artifactId>
        <version>[3.0, 4.0)</version>
    </dependency>
    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-rdbms</artifactId>
        <version>3.1.3</version>
        <scope>runtime</scope>
    </dependency>

および次のバージョンの DN エンハンサー:

    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-enhancer</artifactId>
        <version>3.1.1</version>
    </dependency>

コレクションのオブジェクトやコレクション自体に変更を加えることはありません。実際のところ、コレクションが空の場合でもエラーが発生します...何が間違っているのでしょうか?

追加のデバッグ の詳細 pm.close() ステートメントでデバッグ モードに入ったところ、リスナーを繰り返し処理しているときに、そのうちの 1 つがリスナーのリストから自分自身を削除していることがわかりました。

447468239@qtp-1694835335-71@11277, prio=5, in group 'main', status: 'RUNNING'
  at org.datanucleus.store.connection.ConnectionManagerImpl$1.managedConnectionPostClose(ConnectionManagerImpl.java:247)
  at com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection.close(DatastoreConnectionFactoryImpl.java:147)
  at org.datanucleus.store.connection.ConnectionManagerImpl.closeAllConnections(ConnectionManagerImpl.java:181)
  at org.datanucleus.store.AbstractStoreManager$1.preClose(AbstractStoreManager.java:260)
  at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1112)
  at org.datanucleus.api.jdo.JDOPersistenceManager.internalClose(JDOPersistenceManager.java:359)
  at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.releasePersistenceManager(JDOPersistenceManagerFactory.java:1106)
  at org.datanucleus.api.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:343)
  at net.mycrub.jacasse.persistence.dao.GenericDAO.getAll(GenericDAO.java:43)

ConnectionManagerImpl.java:247 のコード

                    // Remove this listener
                    mconn.removeListener(this);

これは私が自分で追加したリスナーではありません。実際には、Query.closeAll()ステートメント中に追加された DN リスナーでした。これら 2 つの "close" ステートメントのいずれかを保持する必要がありますか?それらは冗長ですか?

4

2 に答える 2

1

このようなことを試しましたか?

public List<OT> getAll()
{
  List<OT> liResult = null;

  PersistenceManager pm = PMF.get().getPersistenceManager();
  Query q = pm.newQuery();
  try
  {
    q.setClass(OT.class);
    liResult = (List<OT>)q.execute();
  }
  finally
  {
    try
    {
      q.closeAll();
    }
    finally
    {
      pm.close();
    }
  }

  return liResult;
}
于 2013-09-19T08:33:03.773 に答える
0

方法はDatastoreManagedConnection#close()単純に

public void close() {
    for (ManagedConnectionResourceListener listener : listeners) {
        listener.managedConnectionPreClose();
    }
    // nothing to actually close
    for (ManagedConnectionResourceListener listener : listeners) {
        listener.managedConnectionPostClose();
    }
}

このConcurrentModificationExceptionコードではlisteners List. 他のコードを並行して実行し、 に追加または削除したりlisteners、 を呼び出しaddListenerたりすることは可能ですかremoveListener?

于 2013-09-17T16:00:09.530 に答える