⬆️ ⬇️

Creating a custom query generator in Spring Data Neo4j (Part 1)

To begin with, the task appeared to generate cypher requests for data classes based on the annotations @NodeEntity , @RelationshipEntity and @Relationship and additional parameters. A query generator was written, but the query string was calculated in runtime and we could not use it as a parameter of the existing @Query annotation, so a new @CustomQuery annotation was added, the processor of which used the written query generator.



Versions of software used:



spring-data-neo4j - 5.0.9.RELEASE

neo4j - 3.4.6

neo4j-ogm - 3.1.4



Adding a custom query generator in Spring Data Neo4j



To add your own mechanism for generating cypher requests for methods of neo4j repositories marked for example, @CustomQuery you are @CustomQuery you need to create the CustomNeo4jRepositoryFactory extends Neo4jRepositoryFactory class CustomNeo4jRepositoryFactory extends Neo4jRepositoryFactory and redefine the getQueryLookupStrategy method in it, it should return a new search strategy for query handlers, it should return a new search strategy for query handlers, it should return a new search strategy for CustomGraphQueryLookupStrategy extends GraphQueryLookupStrategy .



 @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider evaluationContextProvider) { return Optional.of(new CustomGraphQueryLookupStrategy(session)); } 


You also need to extend the standard Neo4jRepositoryFactoryBean class Neo4jRepositoryFactoryBean new CustomNeo4jRepositoryFactoryBean class and override the createRepositoryFactory method. It should return a copy of the new repository factory:



 @Override protected RepositoryFactorySupport createRepositoryFactory(Session session) { return new CustomNeo4jRepositoryFactory(session); } 


In order for Spring Data Neo4j to understand which repository factory bin to use, it must be explicitly indicated in the @EnableNeo4jRepositories annotation in the configuration:



 @EnableNeo4jRepositories(..., repositoryFactoryBeanClass = CustomNeo4jRepositoryFactoryBean.class) 


An additional CustomQuery query query has been CustomQuery . If the repository method is marked with this annotation, the CustomGraphQueryLookupStrategy in the override method resolveQuery will return the object of our query CustomGraphRepositoryQuery extends GraphRepositoryQuery :



 public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory, NamedQueries namedQueries) { if (method.isAnnotationPresent(CustomQuery.class)) { GraphQueryMethod queryMethod = new GraphQueryMethod(method, metadata, factory); return new CustomGraphRepositoryQuery(queryMethod, session, method.getAnnotation(CustomQuery.class)); } else { return super.resolveQuery(method, metadata, factory, namedQueries); } } 


CustomGraphRepositoryQuery implements a getQuery method that returns a Query object, its constructor accepts a cypher query that was built in CustomGraphRepositoryQuery based on CustomQuery annotation CustomQuery and a Method object marked with such annotation:



 @Override protected Query getQuery(Object[] parameters) { return new Query(query, resolveParams(parameters)); } 


The resolveParametres(Object[]) method and resolveParametres(Object[]) used by it are private in GraphRepositoryQuery , so they were simply copied to CustomGraphRepositoryQuery (you can use reflection, this will not affect performance, because query generation occurs before runtime).



Conclusion



Thus, you can declare your mechanism for generating cypher-requests, if necessary.



The following articles will describe the query generator itself, its parameters, the mechanism of operation, problems encountered and their solution.



')

Source: https://habr.com/ru/post/434902/



All Articles