1

I'm writing some unit tests and want to use TimeTree along with Spring repositories, to auto attach event nodes to a time tree. Something like this issue, but I'm using boot 2.0 and SDN5. I think my main issue is I don't know how to set up the configuration so my repositories and my TimeTree use the same GraphDatabaseService. My @Confuration is like this:

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

And my test looks like this:

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

There's a host of errors, but I think they all stem from this one:

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
nmervaillie
  • 1,145
  • 8
  • 20
Alper Akture
  • 2,445
  • 1
  • 30
  • 44

1 Answers1

1

It is because the configuration class redefines some beans already automatically configured by Spring boot (here the Session).

So spring injection does not know how to choose between the 2. Removing the getSession() should help.

A second thing is that your SessionFactory has to use the embedded DB setup in the graphDatabaseService() method. For this, configure an embedded driver with the existing database.

Summary config that should work fine for you :

@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() {
    ...
nmervaillie
  • 1,145
  • 8
  • 20