user3248346
user3248346

Reputation:

Rollback issue with Neo4j

I am following this tutorial but have modified the POM.xml to use version 3.1.0.RELEASE of Spring Data Neo4j. I am experiencing a problem where the graph database does not seem to be instantiated correctly. The only code modification I did from the tutorial code was to replace the deprecated EmbeddedGraphDatabase API with the GraphDatabaseService API in Application.java. Any help would be appreciated.

UPDATE This issue with the EmbdeedGraphDatabase is fixed. Now the issue is with rollback a transaction.

Application.java

package com.me.nosql.neo4j.hello;


import java.io.File;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.kernel.impl.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.Transactional;

@Configuration
@EnableNeo4jRepositories
@EnableAutoConfiguration
@ComponentScan
public class Application extends Neo4jConfiguration implements CommandLineRunner {

    @Autowired
    PersonRepository personRepository;

    public Application() {
        setBasePackage("com/me/nosql/neo4j/hello");
    }

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabase("accessingdataneo4j.db");
    }

    public void run(String... args) throws Exception {

        Person greg = new Person("Greg");
        Person roy = new Person("Roy");
        Person craig = new Person("Craig");

        System.out.println("Before linking up with Neo4j...");
        for (Person person : new Person[]{greg, roy, craig}) {
            System.out.println(person);
        }

        try (Transaction tx = graphDatabaseService().beginTx()) {
            personRepository.save(greg);
            personRepository.save(roy);
            personRepository.save(craig);

            greg = personRepository.findByName(greg.name);
            greg.worksWith(roy);
            greg.worksWith(craig);
            personRepository.save(greg);

            roy = personRepository.findByName(roy.name);
            roy.worksWith(craig);
            // We already know that roy works with greg
            personRepository.save(roy);

            // We already know craig works with roy and greg

            tx.success();
        }

        System.out.println("Lookup each person by name...");
        for (String name : new String[]{greg.name, roy.name, craig.name}) {
            System.out.println(personRepository.findByName(name));
        }

        System.out.println("Looking up who works with Greg...");
        for (Person person : personRepository.findByTeammatesName("Greg")) {
            System.out.println(person.name + " works with Greg.");
        }
    }

    public static void main(String[] args) throws Exception {
        FileUtils.deleteRecursively(new File("accessingdataneo4j.db"));
        SpringApplication.run(Application.class, args);
    }

}

Error Message

Exception in thread "main" java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:637)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:652)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
    at com.me.nosql.neo4j.hello.Application.main(Application.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.neo4j.graphdb.TransactionFailureException: Failed to mark transaction as rollback only.
    at org.neo4j.kernel.TopLevelTransaction.markAsRollbackOnly(TopLevelTransaction.java:97)
    at org.neo4j.kernel.TopLevelTransaction.failure(TopLevelTransaction.java:86)
    at org.neo4j.cypher.internal.spi.v2_0.TransactionBoundQueryContext.close(TransactionBoundQueryContext.scala:59)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingQueryContext.close(DelegatingQueryContext.scala:33)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$$super$close(ExceptionTranslatingQueryContext.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$$anonfun$close$1.apply$mcV$sp(ExceptionTranslatingQueryContext.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$$anonfun$close$1.apply(ExceptionTranslatingQueryContext.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$$anonfun$close$1.apply(ExceptionTranslatingQueryContext.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$$translateException(ExceptionTranslatingQueryContext.scala:149)
    at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.close(ExceptionTranslatingQueryContext.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$close$1.apply$mcV$sp(ClosingIterator.scala:65)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$close$1.apply(ClosingIterator.scala:63)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$close$1.apply(ClosingIterator.scala:63)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.translateException(ClosingIterator.scala:70)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.close(ClosingIterator.scala:62)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.failIfThrows(ClosingIterator.scala:92)
    at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.hasNext(ClosingIterator.scala:34)
    at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.hasNext(PipeExecutionResult.scala:166)
    at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
    at scala.collection.convert.Wrappers$IteratorWrapper.hasNext(Wrappers.scala:29)
    at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult$$anon$1.hasNext(PipeExecutionResult.scala:74)
    at org.neo4j.helpers.collection.IteratorWrapper.hasNext(IteratorWrapper.java:42)
    at com.me.nosql.neo4j.hello.Application.run(Application.java:77)
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:634)
    ... 10 more
Caused by: java.lang.NullPointerException
    at org.neo4j.kernel.TopLevelTransaction.markAsRollbackOnly(TopLevelTransaction.java:93)
    ... 33 more

Upvotes: 0

Views: 963

Answers (3)

Mykhailo Kravchenko
Mykhailo Kravchenko

Reputation: 26

I faced the similar problem and found the hint for the solution here (http://spring.io/guides/gs/accessing-neo4j-data-rest/). I needed to add the constructor like this:

public Application() {
    setBasePackage("name/of/the/base/package");
}

The example ran, created the db and performed queries, all except the last ("Looking up who works with Greg..."). The error was:

Caused by: org.neo4j.graphdb.TransactionFailureException: Failed to mark transaction as rollback only.

I managed to resolve this by wrapping the call in the transaction, just like that:

    Transaction tx = graphDatabase.beginTx();
    try {
        //Do all the work
        tx.success();
    } finally {
        tx.close();
    }

After then, everything worked fine for me.

EDIT: In order to make all transactions persist in DB I changed the following lines to

    try (Transaction tx = graphDatabase().beginTx()) {
        System.out.println("Lookup each person by name...");
        for (String name : new String[]{greg.name, roy.name, craig.name}) {
            System.out.println(personRepository.findByName(name));
        }
        tx.success();
    }

    try (Transaction tx = graphDatabase().beginTx()) {
        System.out.println("Looking up who works with Greg...");
        for (PersonJ person : personRepository.findByTeammatesName("Greg")) {
            System.out.println(person.name + " works with Greg.");
        }
        tx.success();
    }

Upvotes: 1

Michael Hunger
Michael Hunger

Reputation: 41676

Remove this:

@Autowired
GraphDatabase graphDatabase;

And use the bean-method instead:

graphDatabaseService()
// or
graphDatabase()

Try to use CommandlineRunner as a bean and inject the dependency there. Spring doesn't inject beans that are declared in this configuration into the same config instance.

Upvotes: 0

Sumeet Sharma
Sumeet Sharma

Reputation: 2583

Few things you would like to check :

  1. new GraphDatabaseFactory().newEmbeddedDatabase( "accessingdataneo4j.db" ); Check if the path to the db is correct . Try with an absolute address.
  2. Check if you aren't running the GraphDb instance somewhere else.

Upvotes: 0

Related Questions