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
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).
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