Skip to content

Commit 0c8e779

Browse files
GH-2376 - Add readOnly to org.springframework.data.neo4j.core.schema.Property.
Closes #2376.
1 parent 0b8f52b commit 0c8e779

File tree

6 files changed

+75
-4
lines changed

6 files changed

+75
-4
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.neo4j.driver.types.TypeSystem;
4545
import org.springframework.core.CollectionFactory;
4646
import org.springframework.core.KotlinDetector;
47-
import org.springframework.data.annotation.ReadOnlyProperty;
4847
import org.springframework.data.mapping.AssociationHandler;
4948
import org.springframework.data.mapping.MappingException;
5049
import org.springframework.data.mapping.PersistentPropertyAccessor;
@@ -190,7 +189,7 @@ public void write(Object source, Map<String, Object> parameters) {
190189
nodeDescription.doWithProperties((Neo4jPersistentProperty p) -> {
191190

192191
// Skip the internal properties, we don't want them to end up stored as properties
193-
if (p.isInternalIdProperty() || p.isDynamicLabels() || p.isEntity() || p.isVersionProperty() || p.isAnnotationPresent(ReadOnlyProperty.class)) {
192+
if (p.isInternalIdProperty() || p.isDynamicLabels() || p.isEntity() || p.isVersionProperty() || p.isReadOnly()) {
194193
return;
195194
}
196195

src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentProperty.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.neo4j.driver.Value;
2222
import org.neo4j.driver.Values;
23+
import org.springframework.data.annotation.ReadOnlyProperty;
2324
import org.springframework.data.mapping.Association;
2425
import org.springframework.data.mapping.MappingException;
2526
import org.springframework.data.mapping.PersistentEntity;
@@ -319,4 +320,11 @@ static String deriveRelationshipType(String name) {
319320
}
320321
return sb.toString();
321322
}
323+
324+
@Override
325+
public boolean isReadOnly() {
326+
327+
Class<org.springframework.data.neo4j.core.schema.Property> typeOfAnnotation = org.springframework.data.neo4j.core.schema.Property.class;
328+
return isAnnotationPresent(ReadOnlyProperty.class) || (isAnnotationPresent(typeOfAnnotation) && getRequiredAnnotation(typeOfAnnotation).readOnly());
329+
}
322330
}

src/main/java/org/springframework/data/neo4j/core/mapping/Neo4jPersistentProperty.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,11 @@ default String computePrefixWithDelimiter() {
9090
return Optional.of(compositeProperty.prefix()).map(String::trim).filter(s -> !s.isEmpty())
9191
.orElseGet(this::getFieldName) + compositeProperty.delimiter();
9292
}
93+
94+
/**
95+
* @return {@literal true} if this is a read only property.
96+
*/
97+
default boolean isReadOnly() {
98+
return false;
99+
}
93100
}

src/main/java/org/springframework/data/neo4j/core/schema/Property.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@
4949
*/
5050
@AliasFor("value")
5151
String name() default "";
52+
53+
/**
54+
* @return Set this attribute to {@literal true} to prevent writing any value of this property to the graph.
55+
*/
56+
boolean readOnly() default false;
5257
}

src/test/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntityTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
2121

2222
import java.util.Arrays;
23+
import java.util.Collections;
2324
import java.util.HashSet;
2425
import java.util.List;
2526
import java.util.Map;
@@ -29,6 +30,7 @@
2930
import org.junit.jupiter.api.Test;
3031
import org.junit.jupiter.params.ParameterizedTest;
3132
import org.junit.jupiter.params.provider.ValueSource;
33+
import org.springframework.data.annotation.ReadOnlyProperty;
3234
import org.springframework.data.annotation.Transient;
3335
import org.springframework.data.mapping.AssociationHandler;
3436
import org.springframework.data.mapping.MappingException;
@@ -54,6 +56,36 @@ void persistentEntityCreationWorksForCorrectEntity() {
5456
neo4jMappingContext.getPersistentEntity(CorrectEntity2.class);
5557
}
5658

59+
@Nested
60+
class ReadOnlyProperties {
61+
62+
private final Neo4jMappingContext neo4jMappingContext;
63+
64+
ReadOnlyProperties() {
65+
66+
neo4jMappingContext = new Neo4jMappingContext();
67+
neo4jMappingContext.setInitialEntitySet(Collections.singleton(WithAnnotatedProperties.class));
68+
}
69+
70+
@ParameterizedTest // GH-2376
71+
@ValueSource(strings = {"defaultProperty", "defaultAnnotatedProperty", "writableProperty"})
72+
void propertiesShouldBeWritable(String propertyName) {
73+
74+
Neo4jPersistentProperty property = neo4jMappingContext.getPersistentEntity(WithAnnotatedProperties.class)
75+
.getRequiredPersistentProperty(propertyName);
76+
assertThat(property.isReadOnly()).isFalse();
77+
}
78+
79+
@ParameterizedTest // GH-2376, GH-2294
80+
@ValueSource(strings = {"readOnlyProperty", "usingSpringsAnnotation"})
81+
void propertiesShouldBeReadOnly(String propertyName) {
82+
83+
Neo4jPersistentProperty property = neo4jMappingContext.getPersistentEntity(WithAnnotatedProperties.class)
84+
.getRequiredPersistentProperty(propertyName);
85+
assertThat(property.isReadOnly()).isTrue();
86+
}
87+
}
88+
5789
@Nested
5890
class DuplicateProperties {
5991
@Test
@@ -676,4 +708,25 @@ static class OtherEntityLooksLikeHasObserve {
676708
private List<EntityLooksLikeHasObserve> knows;
677709
}
678710

711+
@Node
712+
static class WithAnnotatedProperties {
713+
714+
@Id @GeneratedValue
715+
private Long id;
716+
717+
private String defaultProperty;
718+
719+
@Property
720+
private String defaultAnnotatedProperty;
721+
722+
@Property(readOnly = true)
723+
private String readOnlyProperty;
724+
725+
@ReadOnlyProperty
726+
private String usingSpringsAnnotation;
727+
728+
@SuppressWarnings("DefaultAnnotationParam")
729+
@Property(readOnly = false)
730+
private String writableProperty;
731+
}
679732
}

src/test/java/org/springframework/data/neo4j/integration/issues/gh2289/SkuRO.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ public class SkuRO {
4646
@EqualsAndHashCode.Include
4747
private Long number;
4848

49-
@ReadOnlyProperty
50-
@Property("name")
49+
@Property(value = "name", readOnly = true)
5150
@EqualsAndHashCode.Include
5251
private String name;
5352

0 commit comments

Comments
 (0)