fbiville
fbiville

Reputation: 8950

Neo4j impermanent graph database and schema index creation

I'm trying to run the following snippet (with Neo4j v2.2.1 / impermanent graph database):

@BeforeClass
public static void prepareAll() {
    graphDB = new TestGraphDatabaseFactory().newImpermanentDatabase();
}

// [...]

try (Transaction tx = graphDB.beginTx()) {
    IndexDefinition definition = graphDB.schema()
        .indexFor(Labels.ARTIST)
        .on("name")
        .create();

    graphDB.schema().awaitIndexOnline(definition, XXX, TimeUnit.MILLISECONDS);
    // [...]
    tx.success();
}

No matter how high I set XXX, an IllegalStateException will always be thrown:

java.lang.IllegalStateException: Expected index to come online within a reasonable time.
    at org.neo4j.kernel.impl.coreapi.schema.SchemaImpl.awaitIndexOnline(SchemaImpl.java:172)
    at xxx.Exercise_3_Test.should_create_index_on_name(Exercise_3_Test.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Is this specific to the impermanent graph database?

Thanks a lot for your help!

Upvotes: 1

Views: 325

Answers (2)

phil_20686
phil_20686

Reputation: 4080

The index doesnt get created until the transaction is completed/committed, and the transaction is not marked as complete until the index comes online, so you are stuck in a deadlock error.

You also need to end your try block with tx.success() to tell the database to commit the transaction, rather than roll it back.

Upvotes: 2

Michal Bachman
Michal Bachman

Reputation: 2661

Just split the index creation and the waiting in two separate transactions:

try (Transaction tx = graphDB.beginTx()) {
    graphDB.schema().indexFor(Labels.ARTIST).on("name").create();
    tx.success();
}

try (Transaction tx = graphDB.beginTx()) {
    graphDB.schema().awaitIndexesOnline(XXX, TimeUnit.MILLISECONDS);
    tx.success();
}

Upvotes: 0

Related Questions