简体   繁体   中英

ArangoDB java driver on executing AQL sometimes return NULL and other times the correct result

I am unable to wrap my head around this peculiar issue. I am using arangodb 3.0.10 and arangodb-java-driver 3.0.4.

I am executing a very simple AQL fetch query. (See code below) All my unit tests pass every time and problem never arises when debugging. The problem does not occur all the time (around half the time). It gets even stranger, the most frequent manifestation is NullPointerException at

return cursor.getUniqueResult();

but also got once a ConcurrentModificationException

Questions:

  1. Do I have to manage the database connection? Like closing the driver connection after each use.
  2. Am i doing something completely wrong with the ArangoDB query?

Any hint in the right direction is appreciated.

Error 1:

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

Error 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();
    }

As AntJavaDev said, you access bindVar more than once the same time. When one thread modify bindVar and another tried to build the AQL call at the same time by reading bindVar . This leads to the ConcurrentModificationException .

The NullPointerException results from an AQL call with no result. eg when you clear bindVar and directly after that, execute the AQL in another thread with no content in bindVar .

To your questions: 1. No, you do not have to close the driver connection after each call. 2. Beside the shared bindVar , everything looks correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM