Skip to content
This repository has been archived by the owner on May 3, 2021. It is now read-only.

Commit

Permalink
Add relationship properties mapping.
Browse files Browse the repository at this point in the history
Provides the functionality of defining relationship with
additional property classes represented as a map structure.

Also the mapping and binder functions for loading or saving data
were condensed into central anonymous functions and shifted
their mapping logic to the Neo4jConverter.

Required behaviour changes in the existing code base:
For setting the Driver bean the Neo4jMappingContext must not be an implementation
of a BeanDefinitionRegistryPostProcessor because this would
require setting up the driver bean very early in the start process
that e.g. configuration parameters that also rely on PostProcessor logic
cannot be processed before setting up the driver.
  • Loading branch information
meistermeier committed Dec 20, 2019
1 parent 9dcbe2b commit ee655f8
Show file tree
Hide file tree
Showing 28 changed files with 1,043 additions and 604 deletions.
Expand Up @@ -303,7 +303,7 @@ private <T> ExecutableQuery<T> createExecutableQuery(Class<T> domainType, Statem
PreparedQuery<T> preparedQuery = PreparedQuery.queryFor(domainType)
.withCypherQuery(renderer.render(statement))
.withParameters(parameters)
.usingMappingFunction(this.neo4jMappingContext.getRequiredMappingFunctionFor(domainType))
.usingMappingFunction(neo4jMappingContext.getRequiredMappingFunctionFor(domainType))
.build();
return toExecutableQuery(preparedQuery);
}
Expand Down
Expand Up @@ -18,12 +18,13 @@
*/
package org.neo4j.springframework.data.core.convert;

import java.util.Map;

import org.neo4j.driver.Record;
import org.neo4j.driver.Value;
import org.neo4j.driver.types.TypeSystem;
import org.springframework.dao.TypeMismatchDataAccessException;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.model.ParameterValueProvider;
import org.springframework.data.convert.EntityReader;
import org.springframework.data.convert.EntityWriter;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;

Expand All @@ -34,7 +35,7 @@
* @soundtrack The Kleptones - A Night At The Hip-Hopera
* @since 1.0
*/
public interface Neo4jConverter {
public interface Neo4jConverter extends EntityReader<Object, Record>, EntityWriter<Object, Map<String, Object>> {

/**
* Reads a {@link Value} returned by the driver and converts it into a {@link Neo4jSimpleTypes simple type} supported
Expand All @@ -43,34 +44,21 @@ public interface Neo4jConverter {
* the failed conversion.
*
* @param value The value to be read, may be null.
* @param type The type information describing the target type
* @param type The type information describing the target type.
* @return A simple type or null, if the value was {@literal null} or {@link org.neo4j.driver.Values#NULL}.
* @throws TypeMismatchDataAccessException In case the value cannot be converted to the target type
*/
@Nullable
Object readValue(@Nullable Value value, TypeInformation<?> type);

@Nullable
Value writeValue(@Nullable Object value, TypeInformation<?> type);
Object readValueForProperty(@Nullable Value value, TypeInformation<?> type);

/**
* Returns a {@link PersistentPropertyAccessor} that delegates to {@code targetPropertyAccessor} and applies
* all known conversions before returning a value.
* Converts an {@link Object} to a driver's value object.
*
* @param targetPropertyAccessor The property accessor to delegate to, must not be {@code null}.
* @param <T> The type of the entity to operate on.
* @return A {@link PersistentPropertyAccessor} guaranteed to be not {@code null}.
* @param value The value to get written, may be null.
* @param type The type information describing the target type.
* @return A driver compatible value object.
*/
<T> PersistentPropertyAccessor<T> decoratePropertyAccessor(TypeSystem typeSystem, PersistentPropertyAccessor<T> targetPropertyAccessor);
@Nullable
Value writeValueFromProperty(@Nullable Object value, TypeInformation<?> type);

/**
* Returns a {@link ParameterValueProvider} that delegates to {@code targetParameterValueProvider} and applies
* all known conversions before returning a value.
*
* @param targetParameterValueProvider The parameter value provider to delegate to, must not be {@code null}.
* @param <T> The type of the entity to operate on.
* @return A {@link ParameterValueProvider} guaranteed to be not {@code null}.
*/
<T extends PersistentProperty<T>> ParameterValueProvider<T> decorateParameterValueProvider(
ParameterValueProvider<T> targetParameterValueProvider);
}
Expand Up @@ -18,13 +18,16 @@
*/
package org.neo4j.springframework.data.core.cypher;

import static org.neo4j.springframework.data.core.cypher.Expressions.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apiguardian.api.API;
import org.neo4j.springframework.data.core.cypher.support.TypedSubtree;
import org.neo4j.springframework.data.core.cypher.support.Visitable;
import org.springframework.util.Assert;

/**
Expand Down Expand Up @@ -74,4 +77,9 @@ MapExpression<?> addEntries(List<MapEntry> entries) {
newContent.addAll(entries);
return new MapExpression<>(newContent);
}

@Override
protected Visitable prepareVisit(MapEntry child) {
return child instanceof Expression ? nameOrExpression((Expression) child) : child;
}
}
Expand Up @@ -111,8 +111,8 @@ private static List<MapEntry> createNewContent(Object... content) {
Assert.isTrue(!knownKeys.contains(lastKey), "Duplicate key '" + lastKey + "'");
entry = new KeyValueMapEntry(lastKey, lastExpression);
knownKeys.add(lastKey);
} else if (lastExpression instanceof PropertyLookup) {
entry = (PropertyLookup) lastExpression;
} else if (lastExpression instanceof MapEntry) {
entry = (MapEntry) lastExpression;
} else {
throw new IllegalArgumentException(lastExpression + " of type " + lastExpression.getClass()
+ " cannot be used with an implicit name as map entry.");
Expand Down
Expand Up @@ -37,7 +37,7 @@
*/
@API(status = API.Status.INTERNAL, since = "1.0")
public final class Relationship implements
PatternElement, Named, Expression,
PatternElement, Named, Expression, MapEntry,
ExposesRelationships<RelationshipChain> {

/**
Expand Down

This file was deleted.

0 comments on commit ee655f8

Please sign in to comment.