2016-10-23 1 views
2

私はこの独特の問題を回避することができません。 私はarangodb 3.0.10とarangodb-java-driver 3.0.4を使用しています。ArangoDBのJavaドライバがAQLを実行しているときにNULLを返し、他の時に正しい結果を返す

私は非常に単純なAQLフェッチクエリを実行しています。 (下のコードを参照してください)すべての私のユニットテストが毎回成功し、デバッグ時に問題が発生することはありません。問題は常に発生するわけではありません(時間の半分程度)。それも見知らぬ人を取得し、最も頻度の高い症状は

return cursor.getUniqueResult(); 

でNullPointerExceptionがあるだけでなく、一度ConcurrentModificationException

質問だ:

  1. は、私は、データベース接続を管理する必要はありますか?それぞれの使用後にドライバを閉じるのと同じように、 接続。
  2. ArangoDBで の質問が完全に間違っていますか?

正しい方向へのヒントはありがたいです。

エラー1:

java.lang.NullPointerException 
      at org.xworx.sincapp.dao.UserDAO.get(UserDAO.java:41) 

エラー2:

java.util.ConcurrentModificationException 
     at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437) 
     at java.util.HashMap$EntryIterator.next(HashMap.java:1471) 
     at java.util.HashMap$EntryIterator.next(HashMap.java:1469) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:206) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:145) 
     at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:208) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:145) 
     at com.google.gson.Gson.toJson(Gson.java:593) 
     at com.google.gson.Gson.toJson(Gson.java:572) 
     at com.google.gson.Gson.toJson(Gson.java:527) 
     at com.google.gson.Gson.toJson(Gson.java:507) 
     at com.arangodb.entity.EntityFactory.toJsonString(EntityFactory.java:201) 
     at com.arangodb.entity.EntityFactory.toJsonString(EntityFactory.java:165) 
     at com.arangodb.impl.InternalCursorDriverImpl.getCursor(InternalCursorDriverImpl.java:94) 
     at com.arangodb.impl.InternalCursorDriverImpl.executeCursorEntityQuery(InternalCursorDriverImpl.java:79) 
     at com.arangodb.impl.InternalCursorDriverImpl.executeAqlQuery(InternalCursorDriverImpl.java:148) 
     at com.arangodb.ArangoDriver.executeAqlQuery(ArangoDriver.java:2158) 
     at org.xworx.sincapp.dao.UserDAO.get(UserDAO.java:41) 

ArangoDBConnector

public abstract class ArangoDBConnector { 

protected static ArangoDriver driver; 
protected static ArangoConfigure configure; 

public ArangoDBConnector() { 
    final ArangoConfigure configure = new ArangoConfigure(); 
    configure.loadProperties(ARANGODB_PROPERTIES); 
    configure.init(); 
    final ArangoDriver driver = new ArangoDriver(configure); 

    ArangoDBConnector.configure = configure; 
    ArangoDBConnector.driver = driver; 

} 

UserDAO

@Named 
public class UserDAO extends ArangoDBConnector{ 

    private Map<String, Object> bindVar = new HashMap(); 

    public UserDAO() {} 

    public User get(@NotNull String objectId) { 
     bindVar.clear(); 
     bindVar.put("uuid", objectId); 
     String fetchUserByObjectId = "FOR user IN User FILTER user.uuid == @uuid RETURN user"; 
     CursorResult<User> cursor = null; 
     try { 
      cursor = driver.executeAqlQuery(fetchUserByObjectId, bindVar, driver.getDefaultAqlQueryOptions(), User.class); 
     } catch (ArangoException e) { 
      new ArangoDaoException(e.getErrorMessage()); 
     } 
     return cursor.getUniqueResult(); 
    } 
+2

クラス 'UserDAO'は' @ Named'を宣言しているので、シングルトンです。では、なぜこの変数の状態をプライベートマップ bindVar = new HashMap() 'にしていますか?つまり、同時に(同時の環境でテストやデバッグではなく)同時に呼び出された場合、何が起こるかわからないからです。 – AntJavaDev

+0

ありがとうございました。 – tchoesang

答えて

2

AntJavaDev としては、あなたが同時に何度もbindVar以上にアクセスし、言いました。 1つのスレッドがbindVarを変更し、別のスレッドがbindVarを読み取って同時にAQL呼び出しを作成しようとしたとき。これはConcurrentModificationExceptionにつながります。

NullPointerExceptionは結果のないAQL呼び出しに起因します。例えばbindVarをクリアした直後に、bindVarに内容のない別のスレッドでAQLを実行してください。

ご質問: 1.いいえ、毎回ドライバの接続を閉じる必要はありません。 2.共有されているbindVarの横にすべてが正しいように見えます。

関連する問題