Add support for named queries.

This commit is contained in:
Michael Simons
2019-05-21 12:26:12 +02:00
parent ab8a187607
commit 6c0c5e509e
6 changed files with 76 additions and 5 deletions

View File

@@ -55,12 +55,15 @@ public final class Neo4jQueryLookupStrategy implements QueryLookupStrategy {
NamedQueries namedQueries) {
Neo4jQueryMethod queryMethod = new Neo4jQueryMethod(method, metadata, factory);
String namedQueryName = queryMethod.getNamedQueryName();
if (queryMethod.hasQueryAnnotation()) {
return StringBasedNeo4jQuery
.create(nodeManager, mappingContext, evaluationContextProvider, queryMethod);
if (namedQueries.hasQuery(namedQueryName)) {
return StringBasedNeo4jQuery.create(nodeManager, mappingContext, evaluationContextProvider, queryMethod,
namedQueries.getQuery(namedQueryName));
} else if (queryMethod.hasQueryAnnotation()) {
return StringBasedNeo4jQuery.create(nodeManager, mappingContext, evaluationContextProvider, queryMethod);
} else {
return new PartTreeNeo4jQuery(nodeManager, mappingContext, queryMethod);
}
return new PartTreeNeo4jQuery(nodeManager, mappingContext, queryMethod);
}
}

View File

@@ -33,6 +33,7 @@ import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.SpelEvaluator;
import org.springframework.data.repository.query.SpelQueryContext;
import org.springframework.data.repository.query.SpelQueryContext.SpelExtractor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -112,6 +113,26 @@ final class StringBasedNeo4jQuery extends AbstractNeo4jQuery {
cypherTemplate, queryAnnotation.count(), queryAnnotation.exists(), queryAnnotation.delete());
}
/**
* Create a {@link StringBasedNeo4jQuery} based on an explicit Cypher template.
*
* @param nodeManager
* @param mappingContext
* @param evaluationContextProvider
* @param queryMethod
* @param cypherTemplate The template to use.
* @return A new instance of a String based Neo4j query.
*/
static StringBasedNeo4jQuery create(NodeManager nodeManager, Neo4jMappingContext mappingContext,
QueryMethodEvaluationContextProvider evaluationContextProvider,
Neo4jQueryMethod queryMethod, String cypherTemplate) {
Assert.hasText(cypherTemplate, "Cannot create String based Neo4j query without a cypher template.");
return new StringBasedNeo4jQuery(nodeManager, mappingContext, evaluationContextProvider, queryMethod,
cypherTemplate, false, false, false);
}
private StringBasedNeo4jQuery(NodeManager nodeManager,
Neo4jMappingContext mappingContext, QueryMethodEvaluationContextProvider evaluationContextProvider,
Neo4jQueryMethod queryMethod, String cypherTemplate, boolean countQuery,

View File

@@ -57,6 +57,9 @@ public interface PersonRepository extends Neo4jRepository<PersonWithAllConstruct
Optional<PersonWithAllConstructor> getOptionalPersonViaQuery(@Param("part1") String part1,
@Param("part2") String part2);
Optional<PersonWithAllConstructor> getOptionalPersonViaNamedQuery(@Param("part1") String part1,
@Param("part2") String part2);
@Query("MATCH (n:PersonWithNoConstructor) return n")
List<PersonWithNoConstructor> getAllPersonsWithNoConstructorViaQuery();

View File

@@ -345,6 +345,13 @@ class RepositoryIT {
assertThat(person.get().getName()).isEqualTo(TEST_PERSON1_NAME);
}
@Test
void loadOptionalPersonWithAllConstructorWithSpelParametersAndNamedQuery() {
Optional<PersonWithAllConstructor> person = repository.getOptionalPersonViaNamedQuery(TEST_PERSON1_NAME.substring(0, 2), TEST_PERSON1_NAME.substring(2));
assertThat(person).isPresent();
assertThat(person.get().getName()).isEqualTo(TEST_PERSON1_NAME);
}
@Test
void loadAllPersonsWithNoConstructor() {
List<PersonWithNoConstructor> persons = repository.getAllPersonsWithNoConstructorViaQuery();

View File

@@ -117,6 +117,22 @@ final class RepositoryQueryTest {
PROJECTION_FACTORY, namedQueries);
assertThat(query).isInstanceOf(StringBasedNeo4jQuery.class);
}
@Test
void shouldSelectStringBasedNeo4jQueryForNamedQuery() {
final String namedQueryName = "TestEntity.findAllByANamedQuery";
when(namedQueries.hasQuery(namedQueryName)).thenReturn(true);
when(namedQueries.getQuery(namedQueryName)).thenReturn("MATCH (n) RETURN n");
final Neo4jQueryLookupStrategy lookupStrategy = new Neo4jQueryLookupStrategy(mock(NodeManager.class), mock(
Neo4jMappingContext.class), QueryMethodEvaluationContextProvider.DEFAULT);
RepositoryQuery query = lookupStrategy
.resolveQuery(queryMethod("findAllByANamedQuery"), TEST_REPOSITORY_METADATA,
PROJECTION_FACTORY, namedQueries);
assertThat(query).isInstanceOf(StringBasedNeo4jQuery.class);
}
}
@Nested
@@ -246,6 +262,8 @@ final class RepositoryQueryTest {
@Query
List<TestEntity> annotatedQueryWithoutTemplate();
List<TestEntity> findAllByANamedQuery();
}
private RepositoryQueryTest() {

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2019 "Neo4j,"
# Neo4j Sweden AB [https://neo4j.com]
#
# This file is part of Neo4j.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
PersonWithAllConstructor.getOptionalPersonViaNamedQuery = MATCH (n:PersonWithAllConstructor{name::#{#part1 + #part2}}) return n