From 16296505eb1b7a74ecc4da5126e5a6bfb88e2569 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Tue, 20 Jul 2021 12:01:52 +0200 Subject: [PATCH 1/5] Prepare branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 198f34160a..40f660caa5 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ org.springframework.data spring-data-neo4j - 6.2.0-SNAPSHOT + 6.2.0-NODE-NAMES-SNAPSHOT Spring Data Neo4j Next generation Object-Graph-Mapping for Spring Data. From 92e5a00b542563f28c95ea3f675bc709c917a1b8 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Tue, 20 Jul 2021 12:02:04 +0200 Subject: [PATCH 2/5] Use domainClassName as root node name. --- .../data/neo4j/core/DynamicLabels.java | 11 +++++--- .../data/neo4j/core/Neo4jTemplate.java | 12 ++++----- .../neo4j/core/ReactiveNeo4jTemplate.java | 14 +++++----- .../data/neo4j/core/TemplateSupport.java | 6 ++--- .../data/neo4j/core/mapping/Constants.java | 7 ++++- .../neo4j/core/mapping/CypherGenerator.java | 24 ++++++++++------- .../mapping/DefaultNeo4jPersistentEntity.java | 6 ++--- .../neo4j/core/mapping/IdDescription.java | 26 +++++++++++-------- .../repository/query/CypherAdapterUtils.java | 2 +- .../repository/query/CypherQueryCreator.java | 10 +++---- .../neo4j/repository/query/Predicate.java | 4 +-- .../DefaultNeo4jIsNewStrategyTest.java | 14 +++++----- .../neo4j/core/mapping/IdDescriptionTest.java | 24 ++++++++--------- .../mapping/callback/IdPopulatorTest.java | 3 ++- .../TypeConversionIT.java | 7 ++--- .../CypherdslConditionExecutorIT.java | 3 +-- .../QuerydslNeo4jPredicateExecutorIT.java | 2 +- .../movies/imperative/AdvancedMappingIT.java | 2 +- 18 files changed, 97 insertions(+), 80 deletions(-) diff --git a/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java b/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java index 8469ead8ef..84bc309a09 100644 --- a/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java +++ b/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java @@ -25,6 +25,8 @@ import org.neo4j.cypherdsl.core.Node; import org.neo4j.cypherdsl.core.StatementBuilder.OngoingMatchAndUpdate; import org.springframework.data.neo4j.core.mapping.Constants; +import org.springframework.data.neo4j.core.mapping.NodeDescription; +import org.springframework.lang.Nullable; /** * Decorator for an ongoing update statement that removes obsolete dynamic labels and adds new ones. @@ -33,16 +35,19 @@ */ final class DynamicLabels implements UnaryOperator { - public static final DynamicLabels EMPTY = new DynamicLabels(Collections.emptyList(), Collections.emptyList()); + public static final DynamicLabels EMPTY = new DynamicLabels(null, Collections.emptyList(), Collections.emptyList()); - private static final Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + private final Node rootNode; private final List oldLabels; private final List newLabels; - DynamicLabels(Collection oldLabels, Collection newLabels) { + DynamicLabels(@Nullable NodeDescription nodeDescription, Collection oldLabels, Collection newLabels) { this.oldLabels = new ArrayList<>(oldLabels); this.newLabels = new ArrayList<>(newLabels); + this.rootNode = nodeDescription != null + ? Cypher.anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)) + : Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); } @Override diff --git a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java index 4d3849f7a3..aaa8eb3af9 100644 --- a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java +++ b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java @@ -413,7 +413,7 @@ private DynamicLabels determineDynamicLabels(T entityToBeSaved, Neo4jPersist } Optional> optionalResult = runnableQuery.fetch().one(); - return new DynamicLabels(optionalResult.map(r -> (Collection) r.get(Constants.NAME_OF_LABELS)) + return new DynamicLabels(entityMetaData, optionalResult.map(r -> (Collection) r.get(Constants.NAME_OF_LABELS)) .orElseGet(Collections::emptyList), (Collection) propertyAccessor.getProperty(p)); }).orElse(DynamicLabels.EMPTY); } @@ -545,12 +545,12 @@ public void deleteByIdWithVersion(Object id, Class domainType, Neo4jPersi String nameOfParameter = "id"; Condition condition = entityMetaData.getIdExpression().isEqualTo(parameter(nameOfParameter)) - .and(Cypher.property(Constants.NAME_OF_ROOT_NODE, versionProperty.getPropertyName()) + .and(Cypher.property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData), versionProperty.getPropertyName()) .isEqualTo(parameter(Constants.NAME_OF_VERSION_PARAM)) - .or(Cypher.property(Constants.NAME_OF_ROOT_NODE, versionProperty.getPropertyName()).isNull())); + .or(Cypher.property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData), versionProperty.getPropertyName()).isNull())); Statement statement = cypherGenerator.prepareMatchOf(entityMetaData, condition) - .returning(Constants.NAME_OF_ROOT_NODE).build(); + .returning(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData)).build(); Map parameters = new HashMap<>(); parameters.put(nameOfParameter, convertIdValues(entityMetaData.getRequiredIdProperty(), id)); @@ -971,7 +971,7 @@ private Optional> createFetchSpec() { if (nodesAndRelationshipsById.hasRootNodeIds()) { return Optional.empty(); } - cypherQuery = renderer.render(nodesAndRelationshipsById.toStatement()); + cypherQuery = renderer.render(nodesAndRelationshipsById.toStatement(entityMetaData)); finalParameters = nodesAndRelationshipsById.getParameters(); } else { Statement statement = queryFragments.toStatement(); @@ -1036,7 +1036,7 @@ private void iterateNextLevel(Collection nodeIds, Neo4jPersistentEntity Collection relationships = target.getRelationshipsInHierarchy(preparedQuery.getQueryFragmentsAndParameters().getQueryFragments()::includeField); for (RelationshipDescription relationshipDescription : relationships) { - Node node = anyNode(Constants.NAME_OF_ROOT_NODE); + Node node = anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(target)); Statement statement = cypherGenerator .prepareMatchOf(target, relationshipDescription, null, diff --git a/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java b/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java index 125be51347..ea6347d803 100644 --- a/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java +++ b/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java @@ -422,7 +422,7 @@ private Mono> determineDynamicLabels(T entityToBeSa return runnableQuery.fetch().one().map(m -> (Collection) m.get(Constants.NAME_OF_LABELS)) .switchIfEmpty(Mono.just(Collections.emptyList())) .zipWith(Mono.just((Collection) propertyAccessor.getProperty(p))) - .map(t -> Tuples.of(entityToBeSaved, new DynamicLabels(t.getT1(), t.getT2()))); + .map(t -> Tuples.of(entityToBeSaved, new DynamicLabels(entityMetaData, t.getT1(), t.getT2()))); }).orElse(Mono.just(Tuples.of(entityToBeSaved, DynamicLabels.EMPTY))); } @@ -548,12 +548,12 @@ public Mono deleteByIdWithVersion(Object id, Class domainType, Neo4 String nameOfParameter = "id"; Neo4jPersistentEntity entityMetaData = neo4jMappingContext.getPersistentEntity(domainType); Condition condition = entityMetaData.getIdExpression().isEqualTo(parameter(nameOfParameter)) - .and(Cypher.property(Constants.NAME_OF_ROOT_NODE, versionProperty.getPropertyName()) + .and(Cypher.property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData), versionProperty.getPropertyName()) .isEqualTo(parameter(Constants.NAME_OF_VERSION_PARAM)) - .or(Cypher.property(Constants.NAME_OF_ROOT_NODE, versionProperty.getPropertyName()).isNull())); + .or(Cypher.property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData), versionProperty.getPropertyName()).isNull())); Statement statement = cypherGenerator.prepareMatchOf(entityMetaData, condition) - .returning(Constants.NAME_OF_ROOT_NODE).build(); + .returning(Constants.NAME_OF_TYPED_ROOT_NODE.apply(entityMetaData)).build(); Map parameters = new HashMap<>(); parameters.put(nameOfParameter, convertIdValues(entityMetaData.getRequiredIdProperty(), id)); @@ -612,7 +612,7 @@ private Mono> createExecutableQuery(Class domainType, if (containsPossibleCircles && !queryFragments.isScalarValueReturn()) { return createNodesAndRelationshipsByIdStatementProvider(entityMetaData, queryFragments, queryFragmentsAndParameters.getParameters()) .flatMap(finalQueryAndParameters -> - createExecutableQuery(domainType, resultType, renderer.render(finalQueryAndParameters.toStatement()), + createExecutableQuery(domainType, resultType, renderer.render(finalQueryAndParameters.toStatement(entityMetaData)), finalQueryAndParameters.getParameters())); } @@ -665,7 +665,7 @@ private Flux, Collection>> iterateNextLevel(Collec return Flux.fromIterable(target.getRelationshipsInHierarchy(queryFragments::includeField)) .flatMap(relDe -> { - Node node = anyNode(Constants.NAME_OF_ROOT_NODE); + Node node = anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(target)); Statement statement = cypherGenerator .prepareMatchOf(target, relDe, null, @@ -995,7 +995,7 @@ public Mono> toExecutableQuery(PreparedQuery preparedQ return createNodesAndRelationshipsByIdStatementProvider(entityMetaData, queryFragments, finalParameters) .map(nodesAndRelationshipsById -> { ReactiveNeo4jClient.MappingSpec mappingSpec = this.neo4jClient.query(renderer.render( - nodesAndRelationshipsById.toStatement())) + nodesAndRelationshipsById.toStatement(entityMetaData))) .bindAll(nodesAndRelationshipsById.getParameters()).fetchAs(resultType); ReactiveNeo4jClient.RecordFetchSpec fetchSpec = preparedQuery.getOptionalMappingFunction() diff --git a/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java b/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java index b45a6fb5f7..9b754a5586 100644 --- a/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java +++ b/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java @@ -180,7 +180,7 @@ boolean hasRootNodeIds() { return parameters.get(ROOT_NODE_IDS).isEmpty(); } - Statement toStatement() { + Statement toStatement(NodeDescription nodeDescription) { String rootNodeIds = "rootNodeIds"; String relationshipIds = "relationshipIds"; @@ -195,12 +195,12 @@ Statement toStatement() { .optionalMatch(relatedNodes) .where(Functions.id(relatedNodes).in(Cypher.parameter(relatedNodeIds))) .with( - rootNodes.as(Constants.NAME_OF_ROOT_NODE.getValue()), + rootNodes.as(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription).getValue()), Functions.collectDistinct(relationships).as(Constants.NAME_OF_SYNTHESIZED_RELATIONS), Functions.collectDistinct(relatedNodes).as(Constants.NAME_OF_SYNTHESIZED_RELATED_NODES)) .orderBy(queryFragments.getOrderBy()) .returning( - Constants.NAME_OF_ROOT_NODE.as(Constants.NAME_OF_SYNTHESIZED_ROOT_NODE), + Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription).as(Constants.NAME_OF_SYNTHESIZED_ROOT_NODE), Cypher.name(Constants.NAME_OF_SYNTHESIZED_RELATIONS), Cypher.name(Constants.NAME_OF_SYNTHESIZED_RELATED_NODES) ) diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java index 7b52d658a4..ed8750916d 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java @@ -19,6 +19,9 @@ import org.apiguardian.api.API.Status; import org.neo4j.cypherdsl.core.Cypher; import org.neo4j.cypherdsl.core.SymbolicName; +import org.springframework.util.StringUtils; + +import java.util.function.Function; /** * A pool of constants used in our Cypher generation. These constants may change without further notice and are meant @@ -33,6 +36,9 @@ public final class Constants { public static final SymbolicName NAME_OF_ROOT_NODE = Cypher.name("n"); + public static final Function, SymbolicName> NAME_OF_TYPED_ROOT_NODE = (nodeDescription) -> + Cypher.name(StringUtils.uncapitalize(nodeDescription.getUnderlyingClass().getSimpleName())); + public static final String NAME_OF_INTERNAL_ID = "__internalNeo4jId__"; /** * Indicates the list of dynamic labels. @@ -54,7 +60,6 @@ public final class Constants { public static final String NAME_OF_ENTITY_LIST_PARAM = "__entities__"; public static final String NAME_OF_KNOWN_RELATIONSHIP_PARAM = "__knownRelationShipId__"; public static final String NAME_OF_KNOWN_RELATIONSHIPS_PARAM = "__knownRelationShipIds__"; - public static final String NAME_OF_PATHS = "__paths__"; public static final String NAME_OF_ALL_PROPERTIES = "__allProperties__"; public static final String NAME_OF_SYNTHESIZED_ROOT_NODE = "__sn__"; diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java b/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java index 2fd51f8d64..56aba80821 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java @@ -109,7 +109,7 @@ public StatementBuilder.OrderableOngoingReadingAndWith prepareMatchOf(NodeDescri Node rootNode = createRootNode(nodeDescription); List expressions = new ArrayList<>(); - expressions.add(Constants.NAME_OF_ROOT_NODE); + expressions.add(rootNode.getRequiredSymbolicName()); expressions.add(Functions.id(rootNode).as(Constants.NAME_OF_INTERNAL_ID)); return match(rootNode).where(conditionOrNoCondition(condition)).with(expressions.toArray(new Expression[] {})); @@ -121,7 +121,7 @@ public StatementBuilder.OngoingReading prepareMatchOf(NodeDescription nodeDes String primaryLabel = nodeDescription.getPrimaryLabel(); List additionalLabels = nodeDescription.getAdditionalLabels(); - Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_ROOT_NODE); + Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); StatementBuilder.OngoingReadingWithoutWhere match = null; if (initialMatchOn == null || initialMatchOn.isEmpty()) { @@ -150,7 +150,7 @@ public StatementBuilder.OngoingReading prepareMatchOf(NodeDescription nodeDes String primaryLabel = nodeDescription.getPrimaryLabel(); List additionalLabels = nodeDescription.getAdditionalLabels(); - Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_ROOT_NODE); + Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); StatementBuilder.OngoingReadingWithoutWhere match = null; if (initialMatchOn == null || initialMatchOn.isEmpty()) { @@ -210,7 +210,7 @@ public Node createRootNode(NodeDescription nodeDescription) { String primaryLabel = nodeDescription.getPrimaryLabel(); List additionalLabels = nodeDescription.getAdditionalLabels(); - return node(primaryLabel, additionalLabels).named(Constants.NAME_OF_ROOT_NODE); + return node(primaryLabel, additionalLabels).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); } /** @@ -223,7 +223,7 @@ public Node createRootNode(NodeDescription nodeDescription) { */ public Statement createStatementReturningDynamicLabels(NodeDescription nodeDescription) { - final Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + final Node rootNode = Cypher.anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); Condition versionCondition; if (((Neo4jPersistentEntity) nodeDescription).hasVersionProperty()) { @@ -254,7 +254,7 @@ public Statement prepareDeleteOf(NodeDescription nodeDescription, @Nullable C public Statement prepareDeleteOf(NodeDescription nodeDescription, @Nullable Condition condition, boolean count) { Node rootNode = node(nodeDescription.getPrimaryLabel(), nodeDescription.getAdditionalLabels()) - .named(Constants.NAME_OF_ROOT_NODE); + .named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); OngoingUpdate ongoingUpdate = match(rootNode).where(conditionOrNoCondition(condition)).detachDelete(rootNode); if (count) { return ongoingUpdate.returning(Functions.count(rootNode)).build(); @@ -268,7 +268,7 @@ public Statement prepareSaveOf(NodeDescription nodeDescription, String primaryLabel = nodeDescription.getPrimaryLabel(); List additionalLabels = nodeDescription.getAdditionalLabels(); - Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_ROOT_NODE); + Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); IdDescription idDescription = nodeDescription.getIdDescription(); Parameter idParameter = parameter(Constants.NAME_OF_ID); @@ -356,7 +356,7 @@ public Statement prepareSaveOfMultipleInstancesOf(NodeDescription nodeDescrip "Only entities that use external IDs can be saved in a batch."); Node rootNode = node(nodeDescription.getPrimaryLabel(), nodeDescription.getAdditionalLabels()) - .named(Constants.NAME_OF_ROOT_NODE); + .named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); IdDescription idDescription = nodeDescription.getIdDescription(); String nameOfIdProperty = idDescription.getOptionalGraphPropertyName() @@ -519,7 +519,13 @@ public Collection createReturnStatementForMatch(Neo4jPersistentEntit if (nodeDescription.containsPossibleCircles(includeField)) { return createGenericReturnStatement(); } else { - return Collections.singleton(projectPropertiesAndRelationships(PropertyFilter.RelaxedPropertyPath.withRootType(nodeDescription.getUnderlyingClass()), nodeDescription, Constants.NAME_OF_ROOT_NODE, includeField, null, processedRelationships)); + return Collections.singleton(projectPropertiesAndRelationships( + PropertyFilter.RelaxedPropertyPath.withRootType(nodeDescription.getUnderlyingClass()), + nodeDescription, + Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription), + includeField, + null, + processedRelationships)); } } diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntity.java b/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntity.java index 8d1bd6ae6a..417da4ddef 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntity.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntity.java @@ -420,7 +420,7 @@ private IdDescription computeIdDescription() { // Assigned ids if (generatedValueAnnotation == null) { - return IdDescription.forAssignedIds(propertyName); + return IdDescription.forAssignedIds(Constants.NAME_OF_TYPED_ROOT_NODE.apply(this), propertyName); } Class> idGeneratorClass = generatedValueAnnotation.generatorClass(); @@ -443,11 +443,11 @@ private IdDescription computeIdDescription() { "Internally generated ids can only be assigned to one of " + VALID_GENERATED_ID_TYPES); } - return IdDescription.forInternallyGeneratedIds(); + return IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_TYPED_ROOT_NODE.apply(this)); } // Externally generated ids. - return IdDescription.forExternallyGeneratedIds(idGeneratorClass, idGeneratorRef, propertyName); + return IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_TYPED_ROOT_NODE.apply(this), idGeneratorClass, idGeneratorRef, propertyName); } @Override diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java index 3fecc44357..0b5af67261 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java @@ -22,6 +22,7 @@ import org.neo4j.cypherdsl.core.Expression; import org.neo4j.cypherdsl.core.Functions; import org.neo4j.cypherdsl.core.Node; +import org.neo4j.cypherdsl.core.SymbolicName; import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.IdGenerator; import org.springframework.data.util.Lazy; @@ -54,45 +55,48 @@ public final class IdDescription { private final Lazy idExpression; - public static IdDescription forAssignedIds(String graphPropertyName) { + public static IdDescription forAssignedIds(SymbolicName symbolicName, String graphPropertyName) { Assert.notNull(graphPropertyName, "Graph property name is required."); - return new IdDescription(null, null, graphPropertyName); + return new IdDescription(symbolicName, null, null, graphPropertyName); } - public static IdDescription forInternallyGeneratedIds() { - return new IdDescription(GeneratedValue.InternalIdGenerator.class, null, null); + public static IdDescription forInternallyGeneratedIds(SymbolicName symbolicName) { + return new IdDescription(symbolicName, GeneratedValue.InternalIdGenerator.class, null, null); } - public static IdDescription forExternallyGeneratedIds(@Nullable Class> idGeneratorClass, + public static IdDescription forExternallyGeneratedIds(SymbolicName symbolicName, + @Nullable Class> idGeneratorClass, @Nullable String idGeneratorRef, String graphPropertyName) { Assert.notNull(graphPropertyName, "Graph property name is required."); try { Assert.hasText(idGeneratorRef, "Reference to an ID generator has precedence."); - return new IdDescription(null, idGeneratorRef, graphPropertyName); + return new IdDescription(symbolicName, null, idGeneratorRef, graphPropertyName); } catch (IllegalArgumentException e) { Assert.notNull(idGeneratorClass, "Class of id generator is required."); Assert.isTrue(idGeneratorClass != GeneratedValue.InternalIdGenerator.class, "Cannot use InternalIdGenerator for externally generated ids."); - return new IdDescription(idGeneratorClass, null, graphPropertyName); + return new IdDescription(symbolicName, idGeneratorClass, null, graphPropertyName); } } - private IdDescription(@Nullable Class> idGeneratorClass, @Nullable String idGeneratorRef, - @Nullable String graphPropertyName) { + private IdDescription(@Nullable SymbolicName symbolicName, @Nullable Class> idGeneratorClass, + @Nullable String idGeneratorRef, @Nullable String graphPropertyName) { + this.idGeneratorClass = idGeneratorClass; this.idGeneratorRef = idGeneratorRef != null && idGeneratorRef.isEmpty() ? null : idGeneratorRef; this.graphPropertyName = graphPropertyName; + SymbolicName nodeName = symbolicName != null ? symbolicName : Constants.NAME_OF_ROOT_NODE; this.idExpression = Lazy.of(() -> { - final Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + final Node rootNode = Cypher.anyNode(nodeName); if (this.isInternallyGeneratedId()) { return Functions.id(rootNode); } else { return this.getOptionalGraphPropertyName() - .map(propertyName -> Cypher.property(Constants.NAME_OF_ROOT_NODE, propertyName)).get(); + .map(propertyName -> Cypher.property(nodeName, propertyName)).get(); } }); } diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/CypherAdapterUtils.java b/src/main/java/org/springframework/data/neo4j/repository/query/CypherAdapterUtils.java index f65e56ffcf..67783772f6 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/CypherAdapterUtils.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/CypherAdapterUtils.java @@ -55,7 +55,7 @@ public static Function sortAdapterFor(NodeDescription n boolean propertyIsQualified = domainProperty.contains("."); SymbolicName root; if (!propertyIsQualified) { - root = Constants.NAME_OF_ROOT_NODE; + root = Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription); } else { int indexOfSeparator = domainProperty.indexOf("."); root = Cypher.name(domainProperty.substring(0, indexOfSeparator)); diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryCreator.java b/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryCreator.java index 7d3288427a..6b2c7b2107 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryCreator.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryCreator.java @@ -278,7 +278,7 @@ private QueryFragments createQueryFragments(@Nullable Condition condition, Sort // all the ways we could query for Node startNode = Cypher.node(nodeDescription.getPrimaryLabel(), nodeDescription.getAdditionalLabels()) - .named(Constants.NAME_OF_ROOT_NODE); + .named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); Condition conditionFragment = Optional.ofNullable(condition).orElseGet(Conditions::noCondition); List relationshipChain = new ArrayList<>(); @@ -302,7 +302,7 @@ private QueryFragments createQueryFragments(@Nullable Condition condition, Sort if (queryType == Neo4jQueryType.COUNT) { queryFragments.setReturnExpression(Functions.count(Cypher.asterisk()), true); } else if (queryType == Neo4jQueryType.EXISTS) { - queryFragments.setReturnExpression(Functions.count(Constants.NAME_OF_ROOT_NODE).gt(Cypher.literalOf(0)), true); + queryFragments.setReturnExpression(Functions.count(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)).gt(Cypher.literalOf(0)), true); } else { queryFragments.setReturnBasedOn(nodeDescription, includedProperties, isDistinct); queryFragments.setOrderBy(Stream @@ -535,7 +535,7 @@ private Condition createRangeConditionForProperty(Expression property, Parameter private Property toCypherProperty(Neo4jPersistentProperty persistentProperty) { - return Cypher.property(Constants.NAME_OF_ROOT_NODE, persistentProperty.getPropertyName()); + return Cypher.property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription), persistentProperty.getPropertyName()); } private Expression toCypherProperty(PersistentPropertyPath path, boolean addToLower) { @@ -546,8 +546,8 @@ private Expression toCypherProperty(PersistentPropertyPath rp.getPropertyPath().equals(path)).findFirst().get(); diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java b/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java index fcc163c10b..171c607771 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java @@ -84,7 +84,7 @@ static Predicate create(Neo4jMappingContext mappingContext, Example examp if (!optionalValue.isPresent()) { if (!internalId && matcherAccessor.getNullHandler().equals(ExampleMatcher.NullHandler.INCLUDE)) { - predicate.add(mode, property(Constants.NAME_OF_ROOT_NODE, propertyName).isNull()); + predicate.add(mode, property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(probeNodeDescription), propertyName).isNull()); } continue; } @@ -97,7 +97,7 @@ static Predicate create(Neo4jMappingContext mappingContext, Example examp predicate.add(mode, predicate.neo4jPersistentEntity.getIdExpression().isEqualTo(literalOf(optionalValue.get()))); } else { - Expression property = property(Constants.NAME_OF_ROOT_NODE, propertyName); + Expression property = property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(probeNodeDescription), propertyName); Expression parameter = parameter(propertyName); Condition condition = property.isEqualTo(parameter); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java index 987dc920c9..82a02fb90c 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java @@ -49,7 +49,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(Long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -67,7 +67,7 @@ void shouldDealWithPrimitives() { Object b = new Object(); Object c = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -89,7 +89,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -104,7 +104,7 @@ void shouldDealWithNonPrimitives() { @Test void doesntNeedToDealWithPrimitives() { - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -121,7 +121,7 @@ class Assigned { @Test void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { Object a = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds("na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -134,7 +134,7 @@ void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { void shouldDealWithVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds("na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(String.class).when(versionProperty).getType(); @@ -161,7 +161,7 @@ void shouldDealWithVersion() { void shouldDealWithPrimitiveVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds("na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(int.class).when(versionProperty).getType(); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java index 75e7d0cd62..afab638251 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java @@ -28,34 +28,34 @@ class IdDescriptionTest { @Test void isAssignedShouldWork() { - assertThat(IdDescription.forAssignedIds("foobar").isAssignedId()).isTrue(); - assertThat(IdDescription.forAssignedIds("foobar").isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forAssignedIds("foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isAssignedId()).isTrue(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isInternallyGeneratedId()).isFalse(); } @Test void idIsGeneratedInternallyShouldWork() { - assertThat(IdDescription.forInternallyGeneratedIds().isAssignedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds().isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds().isInternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isAssignedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isInternallyGeneratedId()).isTrue(); } @Test void idIsGeneratedExternally() { - assertThat(IdDescription.forExternallyGeneratedIds(DummyIdGenerator.class, null, "foobar").isAssignedId()) + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isAssignedId()) .isFalse(); assertThat( - IdDescription.forExternallyGeneratedIds(DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) .isTrue(); assertThat( - IdDescription.forExternallyGeneratedIds(DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) .isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(null, "someId", "foobar").isAssignedId()).isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); - assertThat(IdDescription.forExternallyGeneratedIds(null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isAssignedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); } private static class DummyIdGenerator implements IdGenerator { diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java index c23793d817..9156790fb8 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity; import org.springframework.data.neo4j.core.schema.GeneratedValue; @@ -57,7 +58,7 @@ void shouldRejectNullEntity() { @Test void shouldIgnoreInternalIdGenerator() { - IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(); + IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(toBeReturned).when(nodeDescription).getIdDescription(); doReturn(nodeDescription).when(neo4jMappingContext).getRequiredPersistentEntity(Sample.class); diff --git a/src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/TypeConversionIT.java b/src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/TypeConversionIT.java index a4a2cb1994..3b057e421e 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/TypeConversionIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/TypeConversionIT.java @@ -83,8 +83,6 @@ @Neo4jIntegrationTest class TypeConversionIT extends Neo4jConversionsITBase { - private final Driver driver; - @Autowired CypherTypesRepository cypherTypesRepository; private final AdditionalTypesRepository additionalTypesRepository; @@ -96,11 +94,10 @@ class TypeConversionIT extends Neo4jConversionsITBase { private final DefaultConversionService defaultConversionService; - @Autowired TypeConversionIT(Driver driver, CypherTypesRepository cypherTypesRepository, + @Autowired TypeConversionIT(CypherTypesRepository cypherTypesRepository, AdditionalTypesRepository additionalTypesRepository, SpatialTypesRepository spatialTypesRepository, CustomTypesRepository customTypesRepository, Neo4jConversions neo4jConversions, BookmarkCapture bookmarkCapture) { - this.driver = driver; this.cypherTypesRepository = cypherTypesRepository; this.additionalTypesRepository = additionalTypesRepository; this.spatialTypesRepository = spatialTypesRepository; @@ -116,7 +113,7 @@ void thereShallBeNoDefaultValuesForNonExistingAttributes(@Autowired NonExistingP assertThatExceptionOfType(MappingException.class) .isThrownBy(() -> repository.findById(ID_OF_NON_EXISTING_PRIMITIVES_NODE)) .withMessageMatching( - "Error mapping Record<\\{n: \\{__internalNeo4jId__: \\d+, id: NULL, someBoolean: NULL, __nodeLabels__: \\[\"NonExistingPrimitives\"\\]\\}\\}>") + "Error mapping Record<\\{thingWithNonExistingPrimitives: \\{__internalNeo4jId__: \\d+, id: NULL, someBoolean: NULL, __nodeLabels__: \\[\"NonExistingPrimitives\"\\]\\}\\}>") .withStackTraceContaining("unboxBoolean") .withRootCauseInstanceOf(NullPointerException.class); } diff --git a/src/test/java/org/springframework/data/neo4j/integration/imperative/CypherdslConditionExecutorIT.java b/src/test/java/org/springframework/data/neo4j/integration/imperative/CypherdslConditionExecutorIT.java index 8a9035d4f5..7a4cd9d3a8 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/imperative/CypherdslConditionExecutorIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/imperative/CypherdslConditionExecutorIT.java @@ -33,7 +33,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.neo4j.config.AbstractNeo4jConfig; import org.springframework.data.neo4j.core.DatabaseSelectionProvider; -import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager; import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; import org.springframework.data.neo4j.integration.shared.common.Person; @@ -73,7 +72,7 @@ class CypherdslConditionExecutorIT { //CHECKSTYLE:OFF // tag::sdn-mixins.dynamic-conditions.usage[] - Node person = Cypher.node("Person").named(Constants.NAME_OF_ROOT_NODE); // <.> + Node person = Cypher.node("Person").named("person"); // <.> Property firstName = person.property("firstName"); // <.> Property lastName = person.property("lastName"); // end::sdn-mixins.dynamic-conditions.usage[] diff --git a/src/test/java/org/springframework/data/neo4j/integration/imperative/QuerydslNeo4jPredicateExecutorIT.java b/src/test/java/org/springframework/data/neo4j/integration/imperative/QuerydslNeo4jPredicateExecutorIT.java index 8f37c13613..30876625c8 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/imperative/QuerydslNeo4jPredicateExecutorIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/imperative/QuerydslNeo4jPredicateExecutorIT.java @@ -61,7 +61,7 @@ class QuerydslNeo4jPredicateExecutorIT { private final Path lastName; QuerydslNeo4jPredicateExecutorIT() { - this.person = Expressions.path(Person.class, "n"); + this.person = Expressions.path(Person.class, "person"); this.firstName = Expressions.path(String.class, person, "firstName"); this.lastName = Expressions.path(String.class, person, "lastName"); } diff --git a/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java b/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java index a79b0cabb6..c1a21f5684 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java @@ -237,7 +237,7 @@ void cyclicRelationshipsAreExcludedFromProjectionsWithProjections( .containsExactlyInAnyOrder("The Oracle", "Morpheus", "Trinity", "Agent Smith", "Emil", "Neo"); assertThat(logbackCapture.getFormattedMessages()).anyMatch(message -> - message.contains("MATCH (n:`Movie`) WHERE n.title = $0 RETURN n{.title")); + message.contains("MATCH (movie:`Movie`) WHERE movie.title = $0 RETURN movie{.title")); } finally { logbackCapture.resetLogLevel(); } From f3959ab9f33c741fa96b2f3a1933c07976e32202 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Mon, 26 Jul 2021 12:27:34 +0200 Subject: [PATCH 3/5] WIP --- .../springframework/data/neo4j/core/DynamicLabels.java | 4 +--- .../data/neo4j/core/mapping/Constants.java | 6 ++++-- .../data/neo4j/core/mapping/CypherGenerator.java | 2 +- .../data/neo4j/core/mapping/IdDescription.java | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java b/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java index 84bc309a09..474a459252 100644 --- a/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java +++ b/src/main/java/org/springframework/data/neo4j/core/DynamicLabels.java @@ -45,9 +45,7 @@ final class DynamicLabels implements UnaryOperator { DynamicLabels(@Nullable NodeDescription nodeDescription, Collection oldLabels, Collection newLabels) { this.oldLabels = new ArrayList<>(oldLabels); this.newLabels = new ArrayList<>(newLabels); - this.rootNode = nodeDescription != null - ? Cypher.anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)) - : Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + this.rootNode = Cypher.anyNode(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription)); } @Override diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java index ed8750916d..f3df9c2480 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java @@ -36,8 +36,10 @@ public final class Constants { public static final SymbolicName NAME_OF_ROOT_NODE = Cypher.name("n"); - public static final Function, SymbolicName> NAME_OF_TYPED_ROOT_NODE = (nodeDescription) -> - Cypher.name(StringUtils.uncapitalize(nodeDescription.getUnderlyingClass().getSimpleName())); + public static final Function, SymbolicName> NAME_OF_TYPED_ROOT_NODE = + (nodeDescription) -> nodeDescription != null + ? Cypher.name(StringUtils.uncapitalize(nodeDescription.getUnderlyingClass().getSimpleName())) + : Constants.NAME_OF_ROOT_NODE; public static final String NAME_OF_INTERNAL_ID = "__internalNeo4jId__"; /** diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java b/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java index 56aba80821..8ffa208132 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java @@ -618,7 +618,7 @@ private List generateListsFor(PropertyFilter.RelaxedPropertyPath parentP // if we already processed the other way before, do not try to jump in the infinite loop // unless it is a root node relationship - if (!nodeName.equals(Constants.NAME_OF_ROOT_NODE) && relationshipDescription.hasRelationshipObverse() + if (relationshipDescription.hasRelationshipObverse() && processedRelationships.contains(relationshipDescription.getRelationshipObverse())) { continue; } diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java index 0b5af67261..1cadc96173 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java @@ -83,20 +83,20 @@ public static IdDescription forExternallyGeneratedIds(SymbolicName symbolicName, } } - private IdDescription(@Nullable SymbolicName symbolicName, @Nullable Class> idGeneratorClass, + private IdDescription(SymbolicName symbolicName, @Nullable Class> idGeneratorClass, @Nullable String idGeneratorRef, @Nullable String graphPropertyName) { this.idGeneratorClass = idGeneratorClass; this.idGeneratorRef = idGeneratorRef != null && idGeneratorRef.isEmpty() ? null : idGeneratorRef; this.graphPropertyName = graphPropertyName; - SymbolicName nodeName = symbolicName != null ? symbolicName : Constants.NAME_OF_ROOT_NODE; + this.idExpression = Lazy.of(() -> { - final Node rootNode = Cypher.anyNode(nodeName); + final Node rootNode = Cypher.anyNode(symbolicName); if (this.isInternallyGeneratedId()) { return Functions.id(rootNode); } else { return this.getOptionalGraphPropertyName() - .map(propertyName -> Cypher.property(nodeName, propertyName)).get(); + .map(propertyName -> Cypher.property(symbolicName, propertyName)).get(); } }); } From 7faa31dd8d4f3335ecb6631aacd12588a8195312 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Mon, 26 Jul 2021 13:22:13 +0200 Subject: [PATCH 4/5] Polishing. --- .../data/neo4j/core/mapping/Constants.java | 4 +-- .../core/mapping/CypherGeneratorTest.java | 5 ++-- .../DefaultNeo4jIsNewStrategyTest.java | 15 +++++----- .../neo4j/core/mapping/IdDescriptionTest.java | 25 ++++++++-------- .../mapping/callback/IdPopulatorTest.java | 4 +-- .../ReactiveCypherdslStatementExecutorIT.java | 4 +-- .../data/neo4j/test/TestConstants.java | 30 +++++++++++++++++++ 7 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 src/test/java/org/springframework/data/neo4j/test/TestConstants.java diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java index f3df9c2480..5dc2b8aefa 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java @@ -34,12 +34,10 @@ @API(status = Status.EXPERIMENTAL, since = "6.0") public final class Constants { - public static final SymbolicName NAME_OF_ROOT_NODE = Cypher.name("n"); - public static final Function, SymbolicName> NAME_OF_TYPED_ROOT_NODE = (nodeDescription) -> nodeDescription != null ? Cypher.name(StringUtils.uncapitalize(nodeDescription.getUnderlyingClass().getSimpleName())) - : Constants.NAME_OF_ROOT_NODE; + : Cypher.name("n"); public static final String NAME_OF_INTERNAL_ID = "__internalNeo4jId__"; /** diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java index 97f582540d..93cf21249a 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java @@ -39,6 +39,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.neo4j.core.schema.Id; import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.test.TestConstants; /** * @author Davide Fantuzzi @@ -207,7 +208,7 @@ void shouldCreateDynamicRelationshipPathQueryForEnumsWithoutWildcardRelationship Neo4jPersistentEntity persistentEntity = new Neo4jMappingContext() .getPersistentEntity(CyclicEntityWithEnumeratedDynamicRelationship1.class); - org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(TestConstants.NAME_OF_ROOT_NODE); Collection relationships = persistentEntity.getRelationships(); Statement statement = CypherGenerator.INSTANCE.prepareMatchOf( persistentEntity, relationships.iterator().next(), null, null).returning(rootNode).build(); @@ -229,7 +230,7 @@ void shouldCreateDynamicRelationshipPathQueryForStringsWithWildcardRelationships Neo4jPersistentEntity persistentEntity = new Neo4jMappingContext() .getPersistentEntity(CyclicEntityWithStringDynamicRelationship1.class); - org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); + org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(TestConstants.NAME_OF_ROOT_NODE); Collection relationships = persistentEntity.getRelationships(); Statement statement = CypherGenerator.INSTANCE.prepareMatchOf( persistentEntity, relationships.iterator().next(), null, null).returning(rootNode).build(); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java index 82a02fb90c..c2afb73a0d 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java @@ -28,6 +28,7 @@ import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.neo4j.core.schema.IdGenerator; +import org.springframework.data.neo4j.test.TestConstants; import org.springframework.data.support.IsNewStrategy; /** @@ -49,7 +50,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); doReturn(Long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -67,7 +68,7 @@ void shouldDealWithPrimitives() { Object b = new Object(); Object c = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -89,7 +90,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -104,7 +105,7 @@ void shouldDealWithNonPrimitives() { @Test void doesntNeedToDealWithPrimitives() { - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -121,7 +122,7 @@ class Assigned { @Test void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { Object a = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -134,7 +135,7 @@ void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { void shouldDealWithVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(String.class).when(versionProperty).getType(); @@ -161,7 +162,7 @@ void shouldDealWithVersion() { void shouldDealWithPrimitiveVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(int.class).when(versionProperty).getType(); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java index afab638251..7510345c22 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.data.neo4j.core.schema.IdGenerator; +import org.springframework.data.neo4j.test.TestConstants; /** * @author Michael J. Simons @@ -28,34 +29,34 @@ class IdDescriptionTest { @Test void isAssignedShouldWork() { - assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isAssignedId()).isTrue(); - assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isAssignedId()).isTrue(); + assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isInternallyGeneratedId()).isFalse(); } @Test void idIsGeneratedInternallyShouldWork() { - assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isAssignedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isInternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isAssignedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isInternallyGeneratedId()).isTrue(); } @Test void idIsGeneratedExternally() { - assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isAssignedId()) + assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isAssignedId()) .isFalse(); assertThat( - IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) .isTrue(); assertThat( - IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) .isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isAssignedId()).isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); - assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isAssignedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); } private static class DummyIdGenerator implements IdGenerator { diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java index 9156790fb8..7952b2ac76 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity; import org.springframework.data.neo4j.core.schema.GeneratedValue; @@ -34,6 +33,7 @@ import org.springframework.data.neo4j.core.mapping.IdDescription; import org.springframework.data.neo4j.core.schema.IdGenerator; import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.test.TestConstants; @ExtendWith(MockitoExtension.class) class IdPopulatorTest { @@ -58,7 +58,7 @@ void shouldRejectNullEntity() { @Test void shouldIgnoreInternalIdGenerator() { - IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); + IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); doReturn(toBeReturned).when(nodeDescription).getIdDescription(); doReturn(nodeDescription).when(neo4jMappingContext).getRequiredPersistentEntity(Sample.class); diff --git a/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java b/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java index cc3fdf71d4..b2288c30aa 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java @@ -20,6 +20,7 @@ import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager; import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; import org.springframework.data.neo4j.test.BookmarkCapture; +import org.springframework.data.neo4j.test.TestConstants; import org.springframework.transaction.ReactiveTransactionManager; import reactor.test.StepVerifier; @@ -39,7 +40,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.config.AbstractReactiveNeo4jConfig; -import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.integration.shared.common.NamesOnly; import org.springframework.data.neo4j.integration.shared.common.Person; import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; @@ -67,7 +67,7 @@ class ReactiveCypherdslStatementExecutorIT { this.driver = driver; - this.person = Cypher.node("Person").named(Constants.NAME_OF_ROOT_NODE); + this.person = Cypher.node("Person").named(TestConstants.NAME_OF_ROOT_NODE); this.firstName = this.person.property("firstName"); this.lastName = this.person.property("lastName"); } diff --git a/src/test/java/org/springframework/data/neo4j/test/TestConstants.java b/src/test/java/org/springframework/data/neo4j/test/TestConstants.java new file mode 100644 index 0000000000..8fb8d04ee1 --- /dev/null +++ b/src/test/java/org/springframework/data/neo4j/test/TestConstants.java @@ -0,0 +1,30 @@ +/* + * Copyright 2011-2021 the original author or authors. + * + * 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. + */ +package org.springframework.data.neo4j.test; + +import org.neo4j.cypherdsl.core.Cypher; +import org.neo4j.cypherdsl.core.SymbolicName; + +/** + * Constants for test purposes only. + * + * @author Gerrit Meier + */ +public class TestConstants { + + public static final SymbolicName NAME_OF_ROOT_NODE = Cypher.name("n"); + +} From 1fd3f11322cfc34f9a78ea0b6791cc2497da31fd Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Mon, 26 Jul 2021 15:11:21 +0200 Subject: [PATCH 5/5] Review changes. --- .../data/neo4j/core/mapping/Constants.java | 2 ++ .../core/mapping/CypherGeneratorTest.java | 5 ++-- .../DefaultNeo4jIsNewStrategyTest.java | 15 +++++----- .../neo4j/core/mapping/IdDescriptionTest.java | 25 ++++++++-------- .../mapping/callback/IdPopulatorTest.java | 4 +-- .../ReactiveCypherdslStatementExecutorIT.java | 4 +-- .../data/neo4j/test/TestConstants.java | 30 ------------------- 7 files changed, 27 insertions(+), 58 deletions(-) delete mode 100644 src/test/java/org/springframework/data/neo4j/test/TestConstants.java diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java index 5dc2b8aefa..225deff4cb 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/Constants.java @@ -39,6 +39,8 @@ public final class Constants { ? Cypher.name(StringUtils.uncapitalize(nodeDescription.getUnderlyingClass().getSimpleName())) : Cypher.name("n"); + public static final SymbolicName NAME_OF_ROOT_NODE = NAME_OF_TYPED_ROOT_NODE.apply(null); + public static final String NAME_OF_INTERNAL_ID = "__internalNeo4jId__"; /** * Indicates the list of dynamic labels. diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java index 93cf21249a..97f582540d 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/CypherGeneratorTest.java @@ -39,7 +39,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.neo4j.core.schema.Id; import org.springframework.data.neo4j.core.schema.Node; -import org.springframework.data.neo4j.test.TestConstants; /** * @author Davide Fantuzzi @@ -208,7 +207,7 @@ void shouldCreateDynamicRelationshipPathQueryForEnumsWithoutWildcardRelationship Neo4jPersistentEntity persistentEntity = new Neo4jMappingContext() .getPersistentEntity(CyclicEntityWithEnumeratedDynamicRelationship1.class); - org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(TestConstants.NAME_OF_ROOT_NODE); + org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); Collection relationships = persistentEntity.getRelationships(); Statement statement = CypherGenerator.INSTANCE.prepareMatchOf( persistentEntity, relationships.iterator().next(), null, null).returning(rootNode).build(); @@ -230,7 +229,7 @@ void shouldCreateDynamicRelationshipPathQueryForStringsWithWildcardRelationships Neo4jPersistentEntity persistentEntity = new Neo4jMappingContext() .getPersistentEntity(CyclicEntityWithStringDynamicRelationship1.class); - org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(TestConstants.NAME_OF_ROOT_NODE); + org.neo4j.cypherdsl.core.Node rootNode = Cypher.anyNode(Constants.NAME_OF_ROOT_NODE); Collection relationships = persistentEntity.getRelationships(); Statement statement = CypherGenerator.INSTANCE.prepareMatchOf( persistentEntity, relationships.iterator().next(), null, null).returning(rootNode).build(); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java index c2afb73a0d..82a02fb90c 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jIsNewStrategyTest.java @@ -28,7 +28,6 @@ import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.neo4j.core.schema.IdGenerator; -import org.springframework.data.neo4j.test.TestConstants; import org.springframework.data.support.IsNewStrategy; /** @@ -50,7 +49,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(Long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -68,7 +67,7 @@ void shouldDealWithPrimitives() { Object b = new Object(); Object c = new Object(); - IdDescription idDescription = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); + IdDescription idDescription = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -90,7 +89,7 @@ void shouldDealWithNonPrimitives() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -105,7 +104,7 @@ void shouldDealWithNonPrimitives() { @Test void doesntNeedToDealWithPrimitives() { - IdDescription idDescription = IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); + IdDescription idDescription = IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "na"); doReturn(long.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -122,7 +121,7 @@ class Assigned { @Test void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { Object a = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(idDescription).when(entityMetaData).getIdDescription(); doReturn(idProperty).when(entityMetaData).getRequiredIdProperty(); @@ -135,7 +134,7 @@ void shouldAlwaysTreatEntitiesAsNewWithoutVersion() { void shouldDealWithVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(String.class).when(versionProperty).getType(); @@ -162,7 +161,7 @@ void shouldDealWithVersion() { void shouldDealWithPrimitiveVersion() { Object a = new Object(); Object b = new Object(); - IdDescription idDescription = IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "na"); + IdDescription idDescription = IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "na"); doReturn(String.class).when(idProperty).getType(); doReturn(int.class).when(versionProperty).getType(); diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java index 7510345c22..afab638251 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/IdDescriptionTest.java @@ -19,7 +19,6 @@ import org.junit.jupiter.api.Test; import org.springframework.data.neo4j.core.schema.IdGenerator; -import org.springframework.data.neo4j.test.TestConstants; /** * @author Michael J. Simons @@ -29,34 +28,34 @@ class IdDescriptionTest { @Test void isAssignedShouldWork() { - assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isAssignedId()).isTrue(); - assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forAssignedIds(TestConstants.NAME_OF_ROOT_NODE, "foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isAssignedId()).isTrue(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forAssignedIds(Constants.NAME_OF_ROOT_NODE, "foobar").isInternallyGeneratedId()).isFalse(); } @Test void idIsGeneratedInternallyShouldWork() { - assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isAssignedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isExternallyGeneratedId()).isFalse(); - assertThat(IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE).isInternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isAssignedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isExternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE).isInternallyGeneratedId()).isTrue(); } @Test void idIsGeneratedExternally() { - assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isAssignedId()) + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isAssignedId()) .isFalse(); assertThat( - IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isExternallyGeneratedId()) .isTrue(); assertThat( - IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) + IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, DummyIdGenerator.class, null, "foobar").isInternallyGeneratedId()) .isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isAssignedId()).isFalse(); - assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); - assertThat(IdDescription.forExternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isAssignedId()).isFalse(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isExternallyGeneratedId()).isTrue(); + assertThat(IdDescription.forExternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE, null, "someId", "foobar").isInternallyGeneratedId()).isFalse(); } private static class DummyIdGenerator implements IdGenerator { diff --git a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java index 7952b2ac76..9156790fb8 100644 --- a/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java +++ b/src/test/java/org/springframework/data/neo4j/core/mapping/callback/IdPopulatorTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity; import org.springframework.data.neo4j.core.schema.GeneratedValue; @@ -33,7 +34,6 @@ import org.springframework.data.neo4j.core.mapping.IdDescription; import org.springframework.data.neo4j.core.schema.IdGenerator; import org.springframework.data.neo4j.core.schema.Node; -import org.springframework.data.neo4j.test.TestConstants; @ExtendWith(MockitoExtension.class) class IdPopulatorTest { @@ -58,7 +58,7 @@ void shouldRejectNullEntity() { @Test void shouldIgnoreInternalIdGenerator() { - IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(TestConstants.NAME_OF_ROOT_NODE); + IdDescription toBeReturned = IdDescription.forInternallyGeneratedIds(Constants.NAME_OF_ROOT_NODE); doReturn(toBeReturned).when(nodeDescription).getIdDescription(); doReturn(nodeDescription).when(neo4jMappingContext).getRequiredPersistentEntity(Sample.class); diff --git a/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java b/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java index b2288c30aa..cc3fdf71d4 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveCypherdslStatementExecutorIT.java @@ -20,7 +20,6 @@ import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager; import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; import org.springframework.data.neo4j.test.BookmarkCapture; -import org.springframework.data.neo4j.test.TestConstants; import org.springframework.transaction.ReactiveTransactionManager; import reactor.test.StepVerifier; @@ -40,6 +39,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.config.AbstractReactiveNeo4jConfig; +import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.integration.shared.common.NamesOnly; import org.springframework.data.neo4j.integration.shared.common.Person; import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; @@ -67,7 +67,7 @@ class ReactiveCypherdslStatementExecutorIT { this.driver = driver; - this.person = Cypher.node("Person").named(TestConstants.NAME_OF_ROOT_NODE); + this.person = Cypher.node("Person").named(Constants.NAME_OF_ROOT_NODE); this.firstName = this.person.property("firstName"); this.lastName = this.person.property("lastName"); } diff --git a/src/test/java/org/springframework/data/neo4j/test/TestConstants.java b/src/test/java/org/springframework/data/neo4j/test/TestConstants.java deleted file mode 100644 index 8fb8d04ee1..0000000000 --- a/src/test/java/org/springframework/data/neo4j/test/TestConstants.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011-2021 the original author or authors. - * - * 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. - */ -package org.springframework.data.neo4j.test; - -import org.neo4j.cypherdsl.core.Cypher; -import org.neo4j.cypherdsl.core.SymbolicName; - -/** - * Constants for test purposes only. - * - * @author Gerrit Meier - */ -public class TestConstants { - - public static final SymbolicName NAME_OF_ROOT_NODE = Cypher.name("n"); - -}