Skip to content

Commit 81a1f01

Browse files
GH-2207 - Improve the pair of isEntity and isAssociation.
This introduces the idea of a "writable property": Something that can be written "as is" to the database. This is a rather complicated decision to make due to the constructs we support back from Neo4j-OGM days. It goes hand in hand with the decision whether a given property on a entity of the domain describes an association: Everything that is either explicitly annotated with `@Relationship` or is not something that would appear as a graph property is an association. A property on the domain model on the other hand is an entity when it is not something that can be written directly to the graph. That leaves the special case of entities with properties: Those life quite literally between entities, as associations with properties. To make them work in the context of Spring Data Commons, they must be treated as entities and in a dedicated way in our converters. This is now encapsulated in the (already) existing dedicated method `isEntityWithRelationshipProperties()`. However, this method is no longer called from `isEntity()` to solve the cyclic meaning here.
1 parent 46fcb04 commit 81a1f01

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ final class DefaultNeo4jPersistentProperty extends AnnotationBasedPersistentProp
4848
implements Neo4jPersistentProperty {
4949

5050
private final Lazy<String> graphPropertyName;
51+
/**
52+
* A flag whether this is a writeable property: Something that ends up on a Neo4j node or relationship.
53+
*/
54+
private final Lazy<Boolean> isWritableProperty;
55+
/**
56+
* A flag whether this domain property manifests itself as a relationship in Neo4j.
57+
*/
5158
private final Lazy<Boolean> isAssociation;
5259

5360
private final Neo4jMappingContext mappingContext;
@@ -68,15 +75,22 @@ final class DefaultNeo4jPersistentProperty extends AnnotationBasedPersistentProp
6875
this.mappingContext = mappingContext;
6976

7077
this.graphPropertyName = Lazy.of(this::computeGraphPropertyName);
78+
79+
this.isWritableProperty = Lazy.of(() -> {
80+
Class<?> targetType = getActualType();
81+
return simpleTypeHolder.isSimpleType(targetType) // The driver can do this
82+
|| this.mappingContext.hasCustomWriteTarget(targetType) // Some converter in the context can do this
83+
|| isAnnotationPresent(ConvertWith.class) // An explicit converter can do this
84+
|| isComposite(); // Our composite converter can do this
85+
});
86+
7187
this.isAssociation = Lazy.of(() -> {
7288

7389
// Bail out early, this is pretty much explicit
7490
if (isAnnotationPresent(Relationship.class)) {
7591
return true;
7692
}
77-
Class<?> targetType = getActualType();
78-
return !(simpleTypeHolder.isSimpleType(targetType) || this.mappingContext.hasCustomWriteTarget(targetType)
79-
|| isAnnotationPresent(TargetNode.class) || isComposite() || isAnnotationPresent(ConvertWith.class));
93+
return !(isWritableProperty.get() || isAnnotationPresent(TargetNode.class));
8094
});
8195

8296
this.customConversion = Lazy.of(() -> {
@@ -186,7 +200,12 @@ public boolean isAssociation() {
186200

187201
@Override
188202
public boolean isEntity() {
189-
return super.isEntity() && isAssociation() || (isEntityWithRelationshipProperties() && !isComposite());
203+
return super.isEntity() && !isWritableProperty.get();
204+
}
205+
206+
@Override
207+
public boolean isEntityWithRelationshipProperties() {
208+
return isEntity() && ((Neo4jPersistentEntity<?>) getOwner()).isRelationshipPropertiesEntity();
190209
}
191210

192211
private static Function<Object, Value> nullSafeWrite(Function<Object, Value> delegate) {
@@ -207,11 +226,6 @@ public Function<Value, Object> getOptionalReadingConverter() {
207226
return customConversion.getOptional().map(c -> nullSafeRead(c::read)).orElse(null);
208227
}
209228

210-
@Override
211-
public boolean isEntityWithRelationshipProperties() {
212-
return super.isEntity() && ((Neo4jPersistentEntity<?>) getOwner()).isRelationshipPropertiesEntity();
213-
}
214-
215229
/**
216230
* Computes the target name of this property.
217231
*

0 commit comments

Comments
 (0)