@@ -217,6 +217,10 @@ public final class Neo4jTemplate implements Neo4jOperations, BeanFactoryAware {
|
||||
|
||||
private Object convertIdValues(@Nullable Neo4jPersistentProperty idProperty, Object idValues) {
|
||||
|
||||
if (((Neo4jPersistentEntity<?>) idProperty.getOwner()).isUsingInternalIds()) {
|
||||
return idValues;
|
||||
}
|
||||
|
||||
return neo4jMappingContext.getConversionService().writeValue(idValues,
|
||||
ClassTypeInformation.from(idValues.getClass()),
|
||||
idProperty == null ? null : idProperty.getOptionalWritingConverter());
|
||||
@@ -269,9 +273,10 @@ public final class Neo4jTemplate implements Neo4jOperations, BeanFactoryAware {
|
||||
return entityMetaData.getDynamicLabelsProperty().map(p -> {
|
||||
|
||||
PersistentPropertyAccessor propertyAccessor = entityMetaData.getPropertyAccessor(entityToBeSaved);
|
||||
Neo4jPersistentProperty idProperty = entityMetaData.getRequiredIdProperty();
|
||||
Neo4jClient.RunnableSpecTightToDatabase runnableQuery = neo4jClient
|
||||
.query(() -> renderer.render(cypherGenerator.createStatementReturningDynamicLabels(entityMetaData)))
|
||||
.in(inDatabase).bind(propertyAccessor.getProperty(entityMetaData.getRequiredIdProperty()))
|
||||
.in(inDatabase).bind(convertIdValues(idProperty, propertyAccessor.getProperty(idProperty)))
|
||||
.to(Constants.NAME_OF_ID).bind(entityMetaData.getStaticLabels())
|
||||
.to(Constants.NAME_OF_STATIC_LABELS_PARAM);
|
||||
|
||||
|
||||
@@ -220,6 +220,10 @@ public final class ReactiveNeo4jTemplate implements ReactiveNeo4jOperations, Bea
|
||||
|
||||
private Object convertIdValues(@Nullable Neo4jPersistentProperty idProperty, Object idValues) {
|
||||
|
||||
if (((Neo4jPersistentEntity<?>) idProperty.getOwner()).isUsingInternalIds()) {
|
||||
return idValues;
|
||||
}
|
||||
|
||||
return neo4jMappingContext.getConversionService().writeValue(idValues,
|
||||
ClassTypeInformation.from(idValues.getClass()), idProperty == null ? null : idProperty.getOptionalWritingConverter());
|
||||
}
|
||||
@@ -267,9 +271,10 @@ public final class ReactiveNeo4jTemplate implements ReactiveNeo4jOperations, Bea
|
||||
return entityMetaData.getDynamicLabelsProperty().map(p -> {
|
||||
|
||||
PersistentPropertyAccessor propertyAccessor = entityMetaData.getPropertyAccessor(entityToBeSaved);
|
||||
Neo4jPersistentProperty idProperty = entityMetaData.getRequiredIdProperty();
|
||||
ReactiveNeo4jClient.RunnableSpecTightToDatabase runnableQuery = neo4jClient
|
||||
.query(() -> renderer.render(cypherGenerator.createStatementReturningDynamicLabels(entityMetaData)))
|
||||
.in(inDatabase).bind(propertyAccessor.getProperty(entityMetaData.getRequiredIdProperty()))
|
||||
.in(inDatabase).bind(convertIdValues(idProperty, propertyAccessor.getProperty(idProperty)))
|
||||
.to(Constants.NAME_OF_ID).bind(entityMetaData.getStaticLabels()).to(Constants.NAME_OF_STATIC_LABELS_PARAM);
|
||||
|
||||
if (entityMetaData.hasVersionProperty()) {
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDyna
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SimpleDynamicLabelsWithBusinessIdAndVersion;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SimpleDynamicLabelsWithVersion;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SuperNode;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntityWithDynamicLabelsAndIdThatNeedsToBeConverted;
|
||||
import org.springframework.data.neo4j.test.Neo4jExtension;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -357,6 +358,20 @@ public class DynamicLabelsIT {
|
||||
entity -> assertThat(entity.moreLabels).containsExactlyInAnyOrder("SimpleDynamicLabels", "Baz", "Foobar"));
|
||||
}
|
||||
|
||||
@Test // GH-2296
|
||||
void shouldConvertIds(@Autowired Neo4jTemplate template) {
|
||||
|
||||
template.deleteAll(EntityWithDynamicLabelsAndIdThatNeedsToBeConverted.class);
|
||||
EntityWithDynamicLabelsAndIdThatNeedsToBeConverted savedInstance = template
|
||||
.save(new EntityWithDynamicLabelsAndIdThatNeedsToBeConverted("value_1"));
|
||||
|
||||
assertThat(savedInstance.getValue()).isEqualTo("value_1");
|
||||
assertThat(savedInstance.getExtraLabels()).containsExactlyInAnyOrder("value_1");
|
||||
|
||||
Optional<EntityWithDynamicLabelsAndIdThatNeedsToBeConverted> optionalReloadedInstance =
|
||||
template.findById(savedInstance.getId(), EntityWithDynamicLabelsAndIdThatNeedsToBeConverted.class);
|
||||
assertThat(optionalReloadedInstance).hasValueSatisfying(v -> v.getExtraLabels().contains("value_1"));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -26,6 +26,8 @@ import reactor.test.StepVerifier;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
@@ -56,6 +58,7 @@ import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDyna
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SimpleDynamicLabelsWithBusinessIdAndVersion;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SimpleDynamicLabelsWithVersion;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntitiesWithDynamicLabels.SuperNode;
|
||||
import org.springframework.data.neo4j.integration.shared.common.EntityWithDynamicLabelsAndIdThatNeedsToBeConverted;
|
||||
import org.springframework.data.neo4j.test.Neo4jExtension;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -349,6 +352,27 @@ public class ReactiveDynamicLabelsIT {
|
||||
.flatMapMany(entity -> Flux.fromIterable(entity.moreLabels)).sort().as(StepVerifier::create)
|
||||
.expectNext("Baz", "Foobar", "SimpleDynamicLabels");
|
||||
}
|
||||
|
||||
@Test // GH-2296
|
||||
void shouldConvertIds(@Autowired ReactiveNeo4jTemplate template) {
|
||||
|
||||
String label = "value_1";
|
||||
Predicate<EntityWithDynamicLabelsAndIdThatNeedsToBeConverted> expectatations = savedInstance ->
|
||||
label.equals(savedInstance.getValue()) && savedInstance.getExtraLabels().contains(label);
|
||||
|
||||
AtomicReference<UUID> generatedUUID = new AtomicReference<>();
|
||||
template.deleteAll(EntityWithDynamicLabelsAndIdThatNeedsToBeConverted.class)
|
||||
.then(template.save(new EntityWithDynamicLabelsAndIdThatNeedsToBeConverted(label)))
|
||||
.doOnNext(s -> generatedUUID.set(s.getId()))
|
||||
.as(StepVerifier::create)
|
||||
.expectNextMatches(expectatations)
|
||||
.verifyComplete();
|
||||
|
||||
template.findById(generatedUUID.get(), EntityWithDynamicLabelsAndIdThatNeedsToBeConverted.class)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextMatches(expectatations)
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.integration.shared.common;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.neo4j.core.schema.DynamicLabels;
|
||||
import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
||||
import org.springframework.data.neo4j.core.schema.Id;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
|
||||
/**
|
||||
* Provided via Github as reproducer for entities with dynamic labels and ids that are subject to conversion. Needed for GH-2296.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Node
|
||||
public class EntityWithDynamicLabelsAndIdThatNeedsToBeConverted {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID id;
|
||||
|
||||
@DynamicLabels
|
||||
private Set<String> extraLabels;
|
||||
|
||||
private String value;
|
||||
|
||||
public EntityWithDynamicLabelsAndIdThatNeedsToBeConverted(String value) {
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
|
||||
if (Objects.isNull(extraLabels)) {
|
||||
extraLabels = new HashSet<>();
|
||||
}
|
||||
extraLabels.add(value);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Set<String> getExtraLabels() {
|
||||
return extraLabels;
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user