Neo4j的回滚问题

时间:2014-05-26 23:28:51

标签: neo4j spring-data-neo4j

我正在关注this教程,但修改了POM.xml以使用Spring Data Neo4j的3.1.0.RELEASE版本。我遇到的问题是图形数据库似乎没有正确实例化。我在教程代码中做的唯一代码修改是使用EmbeddedGraphDatabase中的GraphDatabaseService API替换已弃用的Application.java API。任何帮助将不胜感激。

更新 EmbdeedGraphDatabase的此问题已修复。现在的问题是回滚事务。

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

}

错误消息

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

3 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,并在此处找到了解决方案的提示(http://spring.io/guides/gs/accessing-neo4j-data-rest/)。 我需要像这样添加构造函数:

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

示例运行,创建了数据库并执行了查询,除了最后一个("查找谁使用Greg ...")。错误是:

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

我设法通过在事务中包装调用来解决这个问题,就像那样:

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

在那之后,一切都很适合我。

编辑:为了使所有交易在DB中保持不变,我将以下行更改为

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

答案 1 :(得分:0)

您想检查的内容很少:

  1. new GraphDatabaseFactory().newEmbeddedDatabase( "accessingdataneo4j.db" );检查数据库的路径是否正确。尝试使用绝对地址。
  2. 检查您是否在其他地方运行GraphDb实例。

答案 2 :(得分:0)

删除它:

@Autowired
GraphDatabase graphDatabase;

使用bean方法代替:

graphDatabaseService()
// or
graphDatabase()

尝试将CommandlineRunner用作bean并在那里注入依赖项。 Spring不会将配置中声明的bean注入同一个配置实例。