如何在使用 boot 2.0 和 Neo4j SDN5 的 spring 单元测试中配置我自己的 GraphDatabaseService 和 GraphAwareRuntime

How to I configure my own GraphDatabaseService and GraphAwareRuntime in a spring unit test with boot 2.0 and Neo4j SDN5

我正在编写一些单元测试,并希望将 TimeTree 与 Spring 存储库一起使用,以将事件节点自动附加到时间树。类似 的问题,但我使用的是 boot 2.0 和 SDN5。我认为我的主要问题是我不知道如何设置配置,所以我的存储库和我的 TimeTree 使用相同的 GraphDatabaseService。我的@Confuration 是这样的:

    @Configuration
    public class SpringConfig {

        @Bean
        public SessionFactory sessionFactory() {
            // with domain entity base package(s)
            return new SessionFactory(configuration(), "org.neo4j.boot.test.domain");
        }

        @Bean
        public org.neo4j.ogm.config.Configuration configuration() {
            return new org.neo4j.ogm.config.Configuration.Builder()
                .uri("bolt://localhost")
                .build();
        }

        @Bean
        public Session getSession() {
            return sessionFactory().openSession();
        }

        @Bean
        public GraphDatabaseService graphDatabaseService() {
            return new GraphDatabaseFactory()
                .newEmbeddedDatabase(new File("/tmp/graphDb"));
        }

        @Bean
        public GraphAwareRuntime graphAwareRuntime() {
            GraphDatabaseService graphDatabaseService = graphDatabaseService();
            GraphAwareRuntime runtime = GraphAwareRuntimeFactory
                .createRuntime(graphDatabaseService);

            runtime.registerModule(new TimeTreeModule("timetree",
                TimeTreeConfiguration
                    .defaultConfiguration()
                    .withAutoAttach(true)
                    .with(new NodeInclusionPolicy() {
                        @Override
                        public Iterable<Node> getAll(GraphDatabaseService graphDatabaseService) {
                            return null;
                        }

                        @Override
                        public boolean include(Node node) {
                            return node.hasLabel(Label.label("User"));
                        }
                    })
                    .withRelationshipType(RelationshipType.withName("CREATED_ON"))
                    .withTimeZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("GMT+1")))
                    .withTimestampProperty("createdOn")
                    .withResolution(Resolution.DAY)
    //                      .withCustomTimeTreeRootProperty("timeTreeName")
                    .withResolution(Resolution.HOUR), graphDatabaseService));
            runtime.start();
            return runtime;
        }
    }

我的测试是这样的:

    User user = new User("Michal");
    user.setCreatedOn(1431937636995l);
    userRepository.save(user);

    GraphUnit.assertSameGraph(graphDb, "CREATE (u:User {name:'Michal', createdOn:1431937636995})," +
            "(root:TimeTreeRoot)," +
            "(root)-[:FIRST]->(year:Year {value:2015})," +
            "(root)-[:CHILD]->(year)," +
            "(root)-[:LAST]->(year)," +
            "(year)-[:FIRST]->(month:Month {value:5})," +
            "(year)-[:CHILD]->(month)," +
            "(year)-[:LAST]->(month)," +
            "(month)-[:FIRST]->(day:Day {value:18})," +
            "(month)-[:CHILD]->(day)," +
            "(month)-[:LAST]->(day)," +
            "(day)<-[:CREATED_ON]-(u)"
    );

    GraphUnit.printGraph(graphDb);
    graphDb.shutdown();

有很多错误,但我认为它们都源于这个错误:

Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to 
instantiate [org.springframework.data.repository.support.Repositories]: 
Factory method 'repositories' threw exception; nested exception is 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error 
creating bean with name 'userRepository': Unsatisfied dependency 
expressed through method 'setSession' parameter 0; nested exception is 
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No 
qualifying bean of type 'org.neo4j.ogm.session.Session' available: 
expected single matching bean but found 2: getSession,
org.springframework.data.neo4j.transaction.SharedSessionCreator#0

这是因为配置class重新定义了一些已经由Spring启动自动配置的bean(这里是Session)。

所以spring注入不知道2中怎么取舍。 删除 getSession() 应该会有帮助。

第二件事是您的 SessionFactory 必须在 graphDatabaseService() 方法中使用嵌入式数据库设置。为此,使用现有数据库配置嵌入式驱动程序。

应该适合您的概要配置:

@Bean
public SessionFactory sessionFactory() {
    EmbeddedDriver driver = new EmbeddedDriver(graphDatabaseService());
    return new SessionFactory(driver, "org.neo4j.boot.test.domain");
}

@Bean
public PlatformTransactionManager transactionManager() {
    return new Neo4jTransactionManager(sessionFactory());
}

@Bean
public GraphDatabaseService graphDatabaseService() {
    return new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder().newGraphDatabase();
}

@Bean
public GraphAwareRuntime graphAwareRuntime() {
    ...