SexyMF
SexyMF

Reputation: 11165

Spring for neo4j how to inject Neo4jRepository

All the examples I see in the official documentation is inheriting from Neo4jRepository<T, Long> and not injecting.

And I also see that queries can be run with @Query("match...") annotation. I don't want to run @Query since I need to build the query in runtime.

How can I inject something like Neo4jRepository and use in my beans for running queries and such?

Thanks

Upvotes: 0

Views: 155

Answers (1)

Dima Patserkovskyi
Dima Patserkovskyi

Reputation: 743

In Spring Data Neo4j you cannot run runtime-defined queries via Repository concept. What you can do, is to run CYPHER queries via Session, and here you have two options:

1. Neo4j OGM

OGM is an object-graph mapping library provided by Neo4j. In short, you can create a Session via Neo4jSessionFactory, and run queries having all converting from graph data to your objects in place, the same as with Repository.

You can initialise factory:

    private SessionFactory sessionFactory = new SessionFactory(configuration, "path.to.domains.package");

and then just open session when you need it:

    public Session getNeo4jSession() {
        return sessionFactory.openSession();
    }

Read more on Neo4j Documentation and Spring Documentation

2. Neo4j Drivers

It is a similar way as you can query a SQL with JDBCTemplate. You can create a session via Driver and get a raw data from queries. Here is an example of a service, which could help you to perform a simple transformation:

@Component
public class Neo4jBoltCypherExecutor implements CypherExecutor {

    @org.springframework.beans.factory.annotation.Value("${neo4j.bolt.url}")
    private String boltUrl;

    @org.springframework.beans.factory.annotation.Value("${neo4j.bolt.user}")
    private String user;

    @org.springframework.beans.factory.annotation.Value("${neo4j.bolt.pass}")
    private String pass;

    private Driver neo4jDriver;


    @PostConstruct
    public void postConstruct() {
        AuthToken token = (pass != null && !pass.isEmpty()) ? AuthTokens.basic(user, pass) : AuthTokens.none();
        neo4jDriver = GraphDatabase
                .driver(boltUrl, token, Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE)
                .toConfig());
    }

    @Override
    public List<Map<String, Object>> run(String query, Map<String, Object> params) {
        try (Session session = neo4jDriver.session()) {
            return session.run(query, params).list(r -> r.asMap(Neo4jBoltCypherExecutor::convert));
        }
    }


    static private Object convert(Value value) {
        switch (value.type().name()) {
            case "PATH":
                return value.asList(Neo4jBoltCypherExecutor::convert);
            case "NODE":
            case "RELATIONSHIP":
                return value.asMap();
        }
        return value.asObject();
    }
}

Read more on Neo4j Documentation

Upvotes: 1

Related Questions