making all the tests green again
merged pull requests from ractive fixed handling in ManagedSet fixed cypher query executer initialization extracted EntityStateHandler to resolve cyclic dependency introduced different modes for the initialization provided by the namespace fixed illegal method override for inherited persist
This commit is contained in:
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
@@ -32,22 +33,40 @@ import static org.springframework.util.StringUtils.hasText;
|
||||
public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
private static final String GRAPH_DATABASE_SERVICE = "graphDatabaseService";
|
||||
public static final String ASPECTJ_CONFIG = "org.springframework.data.neo4j.config.Neo4jAspectConfiguration";
|
||||
public static final String CROSS_STORE_CONFIG = "org.springframework.data.neo4j.config.CrossStoreNeo4jConfiguration";
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) {
|
||||
BeanDefinitionBuilder configBuilder = createConfigurationBeanDefinition();
|
||||
BeanDefinitionBuilder configBuilder = createConfigurationBeanDefinition(element);
|
||||
setupGraphDatabase(element, context, configBuilder);
|
||||
setupEntityManagerFactory(element, configBuilder);
|
||||
setupConfigurationClassPostProcessor(context);
|
||||
return getSourcedBeanDefinition(configBuilder, element, context);
|
||||
}
|
||||
|
||||
private BeanDefinitionBuilder createConfigurationBeanDefinition() {
|
||||
BeanDefinitionBuilder configBuilder = BeanDefinitionBuilder.rootBeanDefinition(Neo4jConfiguration.class);
|
||||
|
||||
private BeanDefinitionBuilder createConfigurationBeanDefinition(Element element) {
|
||||
BeanDefinitionBuilder configBuilder = createConfigBuilderByMode(element);
|
||||
configBuilder.setAutowireMode(Autowire.BY_TYPE.value());
|
||||
return configBuilder;
|
||||
}
|
||||
|
||||
// todo cross-store
|
||||
private BeanDefinitionBuilder createConfigBuilderByMode(Element element) {
|
||||
if (isModeCrossStore(element)) return BeanDefinitionBuilder.rootBeanDefinition(CROSS_STORE_CONFIG);
|
||||
if (isModeAspectJ()) return BeanDefinitionBuilder.rootBeanDefinition(ASPECTJ_CONFIG);
|
||||
return BeanDefinitionBuilder.rootBeanDefinition(Neo4jConfiguration.class);
|
||||
}
|
||||
|
||||
private boolean isModeCrossStore(Element element) {
|
||||
return isModeAspectJ() && isEntityManagerFactoryConfigured(element);
|
||||
}
|
||||
|
||||
private boolean isModeAspectJ() {
|
||||
return ClassUtils.isPresent(ASPECTJ_CONFIG, getClass().getClassLoader());
|
||||
}
|
||||
|
||||
private void setupConfigurationClassPostProcessor(final ParserContext parserContext) {
|
||||
BeanDefinitionRegistry beanDefinitionRegistry = parserContext.getRegistry();
|
||||
|
||||
@@ -72,12 +91,17 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser
|
||||
}
|
||||
|
||||
private void setupEntityManagerFactory(Element element, BeanDefinitionBuilder configBuilder) {
|
||||
String entityManagerFactory = element.getAttribute("entityManagerFactory");
|
||||
if (hasText(entityManagerFactory)) {
|
||||
if (isEntityManagerFactoryConfigured(element)) {
|
||||
String entityManagerFactory = element.getAttribute("entityManagerFactory");
|
||||
configBuilder.addPropertyReference("entityManagerFactory", entityManagerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEntityManagerFactoryConfigured(Element element) {
|
||||
String entityManagerFactory = element.getAttribute("entityManagerFactory");
|
||||
return hasText(entityManagerFactory);
|
||||
}
|
||||
|
||||
private String handleStoreDir(Element element, ParserContext context, BeanDefinitionBuilder configBuilder) {
|
||||
String storeDir = element.getAttribute("storeDirectory");
|
||||
if (!hasText(storeDir)) return null;
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.data.neo4j.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.validation.Validator;
|
||||
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
@@ -30,8 +27,6 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
|
||||
|
||||
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
|
||||
import org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean;
|
||||
import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
|
||||
@@ -40,6 +35,7 @@ import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jNodeConverterImpl;
|
||||
import org.springframework.data.neo4j.repository.DirectGraphRepositoryFactory;
|
||||
import org.springframework.data.neo4j.support.EntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.EntityStateHandler;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
|
||||
@@ -51,6 +47,9 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
import org.springframework.transaction.jta.UserTransactionAdapter;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.validation.Validator;
|
||||
|
||||
/**
|
||||
* Abstract base class for code based configuration of Spring managed Neo4j infrastructure.
|
||||
* <p>Subclasses are required to provide an implementation of graphDbService ....
|
||||
@@ -87,6 +86,7 @@ public abstract class Neo4jConfiguration {
|
||||
gdc.setConversionService(conversionService());
|
||||
gdc.setMappingContext(mappingContext());
|
||||
gdc.setConverter(neo4jConverter());
|
||||
gdc.setEntityStateHandler(entityStateHandler());
|
||||
gdc.setNodeTypeRepresentationStrategy(typeRepresentationStrategyFactory.getNodeTypeRepresentationStrategy());
|
||||
gdc.setRelationshipTypeRepresentationStrategy(typeRepresentationStrategyFactory.getRelationshipTypeRepresentationStrategy());
|
||||
if (validator!=null) {
|
||||
@@ -95,6 +95,11 @@ public abstract class Neo4jConfiguration {
|
||||
return gdc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityStateHandler entityStateHandler() {
|
||||
return new EntityStateHandler(mappingContext(),graphDatabaseService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Neo4jNodeConverterImpl neo4jConverter() throws Exception {
|
||||
return new Neo4jNodeConverterImpl();
|
||||
@@ -106,13 +111,13 @@ public abstract class Neo4jConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected RelationshipEntityInstantiator graphRelationshipInstantiator() {
|
||||
return new RelationshipEntityInstantiator(mappingContext());
|
||||
protected RelationshipEntityInstantiator graphRelationshipInstantiator() throws Exception {
|
||||
return new RelationshipEntityInstantiator(entityStateHandler());
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected EntityInstantiator<Node> graphEntityInstantiator() {
|
||||
return new NodeEntityInstantiator(mappingContext());
|
||||
protected EntityInstantiator<Node> graphEntityInstantiator() throws Exception {
|
||||
return new NodeEntityInstantiator(entityStateHandler());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2011 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
|
||||
*
|
||||
* http://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.fieldaccess;
|
||||
|
||||
import org.neo4j.graphdb.PropertyContainer;
|
||||
import org.neo4j.helpers.collection.IterableWrapper;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
|
||||
/**
|
||||
* Simple wrapper to create an Iterable over @NodeEntities or @RelationshipEntities from an iterable over Nodes or Relationships.
|
||||
* Creates NodeEntities on the fly while iterating the Iterator from original iterable.
|
||||
*/
|
||||
public class GraphBackedEntityIterableWrapper<STATE extends PropertyContainer, ENTITY> extends IterableWrapper<ENTITY, STATE> {
|
||||
private final Class<ENTITY> targetType;
|
||||
private final GraphDatabaseContext graphDatabaseContext;
|
||||
|
||||
public GraphBackedEntityIterableWrapper(Iterable<STATE> iterable, Class<ENTITY> targetType, final GraphDatabaseContext graphDatabaseContext) {
|
||||
super(iterable);
|
||||
this.targetType = targetType;
|
||||
this.graphDatabaseContext = graphDatabaseContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ENTITY underlyingObjectToObject(STATE s) {
|
||||
return graphDatabaseContext.createEntityFromState(s, targetType);
|
||||
}
|
||||
|
||||
public static <S extends PropertyContainer, E> GraphBackedEntityIterableWrapper<S, E> create(
|
||||
Iterable<S> iterable, Class<E> targetType, final GraphDatabaseContext graphDatabaseContext) {
|
||||
return new GraphBackedEntityIterableWrapper<S, E>(iterable, targetType, graphDatabaseContext);
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
package org.springframework.data.neo4j.fieldaccess;
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
|
||||
import org.springframework.data.neo4j.core.EntityState;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.DoReturn;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.data.neo4j.support.ManagedEntity;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
@@ -68,15 +69,20 @@ public class ManagedFieldAccessorSet<T> extends AbstractSet<T> {
|
||||
}
|
||||
|
||||
private void update() {
|
||||
final Neo4jPersistentEntity<?> persistentEntity = property.getOwner();
|
||||
if (persistentEntity.isNodeEntity()) {
|
||||
updateValue();
|
||||
}
|
||||
if (persistentEntity.isRelationshipEntity()) {
|
||||
if (ctx.isManaged(entity)) {
|
||||
updateValueWithState(((ManagedEntity)entity).getEntityState());
|
||||
} else {
|
||||
updateValue();
|
||||
}
|
||||
}
|
||||
|
||||
private Object updateValueWithState(EntityState entityState) {
|
||||
final Object newValue = entityState.setValue(property, delegate);
|
||||
if (newValue instanceof DoReturn) return DoReturn.unwrap(newValue);
|
||||
property.setValue(entity, newValue);
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private Object updateValue() {
|
||||
final Object newValue = fieldAccessor.setValue(entity,delegate);
|
||||
if (newValue instanceof DoReturn) return DoReturn.unwrap(newValue);
|
||||
|
||||
@@ -15,18 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.neo4j.fieldaccess;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.springframework.data.neo4j.core.EntityState;
|
||||
|
||||
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.DoReturn;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import scala.annotation.target.field;
|
||||
import org.springframework.data.neo4j.support.ManagedEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Updates the entity containing such a ManagedPrefixedDynamicProperties when some property is added, changed or
|
||||
@@ -82,10 +77,6 @@ public class ManagedPrefixedDynamicProperties extends PrefixedDynamicProperties
|
||||
return d;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
updateValue();
|
||||
}
|
||||
|
||||
private Object updateValue() {
|
||||
final Object newValue = fieldAccessor.setValue(entity, this);
|
||||
if (newValue instanceof DoReturn)
|
||||
@@ -93,4 +84,19 @@ public class ManagedPrefixedDynamicProperties extends PrefixedDynamicProperties
|
||||
property.setValue(entity, newValue);
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (graphDatabaseContext.isManaged(entity)) {
|
||||
updateValueWithState(((ManagedEntity)entity).getEntityState());
|
||||
} else {
|
||||
updateValue();
|
||||
}
|
||||
}
|
||||
|
||||
private Object updateValueWithState(EntityState entityState) {
|
||||
final Object newValue = entityState.setValue(property, this);
|
||||
if (newValue instanceof DoReturn) return DoReturn.unwrap(newValue);
|
||||
property.setValue(entity, newValue);
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,8 @@ import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -59,7 +56,7 @@ public abstract class NodeToNodesRelationshipFieldAccessor extends AbstractNodeR
|
||||
|
||||
@Override
|
||||
protected Node getState(final Object entity) {
|
||||
return property.getOwner().getPersistentState(entity, graphDatabaseContext);
|
||||
return graphDatabaseContext.getPersistentState(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,17 +16,15 @@
|
||||
|
||||
package org.springframework.data.neo4j.fieldaccess;
|
||||
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.mapping.RelationshipInfo;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.springframework.data.neo4j.support.DoReturn.doReturn;
|
||||
|
||||
public class OneToNRelationshipEntityFieldAccessorFactory implements FieldAccessorFactory {
|
||||
@@ -68,22 +66,16 @@ public class OneToNRelationshipEntityFieldAccessorFactory implements FieldAccess
|
||||
@Override
|
||||
public Object getValue(final Object entity) {
|
||||
checkUnderlyingNode(entity);
|
||||
final Set<?> result = createEntitySetFromRelationships(entity);
|
||||
return doReturn(new ManagedFieldAccessorSet(entity, result, property,graphDatabaseContext, this));
|
||||
}
|
||||
return doReturn(iterableFrom(entity));
|
||||
}
|
||||
|
||||
private Set<?> createEntitySetFromRelationships(final Object entity) {
|
||||
final Set<Object> result = new HashSet<Object>();
|
||||
for (final Relationship rel : getStatesFromEntity(entity)) {
|
||||
final Object relationshipEntity = graphDatabaseContext.createEntityFromState(rel, relatedType);
|
||||
result.add(relationshipEntity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private GraphBackedEntityIterableWrapper<Relationship, ?> iterableFrom(final Object entity) {
|
||||
return GraphBackedEntityIterableWrapper.create(getStatesFromEntity(entity), relatedType, graphDatabaseContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Relationship> getStatesFromEntity(final Object entity) {
|
||||
final Node persistentState = property.getOwner().getPersistentState(entity, graphDatabaseContext);
|
||||
final Node persistentState = getState(entity);
|
||||
return persistentState.getRelationships(type, direction);
|
||||
}
|
||||
|
||||
@@ -94,7 +86,7 @@ public class OneToNRelationshipEntityFieldAccessorFactory implements FieldAccess
|
||||
|
||||
@Override
|
||||
protected Node getState(final Object entity) {
|
||||
return property.getOwner().getPersistentState(entity, graphDatabaseContext);
|
||||
return graphDatabaseContext.getPersistentState(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.data.neo4j.mapping.RelationshipInfo;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.springframework.data.neo4j.support.DoReturn.doReturn;
|
||||
@@ -73,5 +74,9 @@ public class OneToNRelationshipFieldAccessorFactory extends NodeRelationshipFiel
|
||||
return doReturn(createManagedSet(entity, result));
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public Object getDefaultImplementation() {
|
||||
return new HashSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ public interface Neo4jPersistentEntity<T> extends PersistentEntity<T, Neo4jPersi
|
||||
|
||||
void setPersistentState(Object entity, PropertyContainer pc);
|
||||
|
||||
<T extends PropertyContainer> T getPersistentState(Object entity, GraphDatabaseContext service);
|
||||
Object getPersistentId(Object entity);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.RelationshipEntity;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -97,19 +96,10 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends PropertyContainer> T getPersistentState(Object entity, GraphDatabaseContext service) {
|
||||
public Object getPersistentId(Object entity) {
|
||||
final Neo4jPersistentProperty idProperty = getIdProperty();
|
||||
if (idProperty==null) throw new MappingException("No field annotated with @GraphId found in "+ getEntityName());
|
||||
if (!Number.class.isAssignableFrom(idProperty.getType())) throw new IllegalArgumentException("The id of "+getEntityName()+" "+idProperty+" is not a number");
|
||||
final Number id = (Number) idProperty.getValue(entity);
|
||||
if (id==null) return null; // todo create new node?
|
||||
if (isNodeEntity()) {
|
||||
return (T) service.getNodeById(id.longValue());
|
||||
}
|
||||
if (isRelationshipEntity()) {
|
||||
return (T) service.getRelationshipById(id.longValue());
|
||||
}
|
||||
throw new IllegalArgumentException("The entity "+getEntityName()+" has to be either annotated with @NodeEntity or @RelationshipEntity");
|
||||
return idProperty.getValue(entity);
|
||||
}
|
||||
|
||||
public String getEntityName() {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright 2011 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
|
||||
*
|
||||
* http://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.support;
|
||||
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.PropertyContainer;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntityImpl;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.10.11
|
||||
*/
|
||||
public class EntityStateHandler {
|
||||
|
||||
private Neo4jMappingContext mappingContext;
|
||||
private final GraphDatabaseService service;
|
||||
|
||||
public EntityStateHandler(Neo4jMappingContext mappingContext, GraphDatabaseService service) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public <S extends PropertyContainer> void setPersistentState(Object entity, S state) {
|
||||
if (entity instanceof PropertyContainer) {
|
||||
return;
|
||||
}
|
||||
if (isManaged(entity)) {
|
||||
((ManagedEntity<S,Object>) entity).setPersistentState(state);
|
||||
return;
|
||||
}
|
||||
final Class<?> type = entity.getClass();
|
||||
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
|
||||
persistentEntity.setPersistentState(entity, state);
|
||||
}
|
||||
|
||||
public boolean isManaged(Object entity) {
|
||||
return entity instanceof ManagedEntity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends PropertyContainer> S getPersistentState(Object entity) {
|
||||
if (entity instanceof PropertyContainer) {
|
||||
return (S) entity;
|
||||
}
|
||||
if (isManaged(entity)) {
|
||||
return ((ManagedEntity<S,Object>) entity).getPersistentState();
|
||||
}
|
||||
final Class<?> type = entity.getClass();
|
||||
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
|
||||
final Object id = persistentEntity.getPersistentId(entity);
|
||||
if (id == null) return null; // todo create new node?
|
||||
if (!(id instanceof Number))
|
||||
throw new IllegalArgumentException("The id of " + persistentEntity.getEntityName() + " " + persistentEntity.getIdProperty() + " is not a number");
|
||||
long graphId = ((Number) id).longValue();
|
||||
if (isNodeEntity(type)) {
|
||||
return (S) service.getNodeById(graphId);
|
||||
}
|
||||
if (isRelationshipEntity(type)) {
|
||||
return (S) service.getRelationshipById(graphId);
|
||||
}
|
||||
throw new IllegalArgumentException("The entity " + persistentEntity.getEntityName() + " has to be either annotated with @NodeEntity or @RelationshipEntity");
|
||||
}
|
||||
|
||||
public boolean isNodeEntity(Class<?> targetType) {
|
||||
return mappingContext.isNodeEntity(targetType);
|
||||
}
|
||||
|
||||
public boolean isRelationshipEntity(Class targetType) {
|
||||
return mappingContext.isRelationshipEntity(targetType);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import org.springframework.data.neo4j.annotation.Indexed;
|
||||
import org.springframework.data.neo4j.core.*;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jNodeConverter;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntityImpl;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
@@ -67,7 +66,8 @@ public class GraphDatabaseContext {
|
||||
private RelationshipTypeRepresentationStrategy relationshipTypeRepresentationStrategy;
|
||||
|
||||
private Neo4jMappingContext mappingContext;
|
||||
private final CypherQueryExecutor executor = new CypherQueryExecutor(this);
|
||||
private CypherQueryExecutor cypherQueryExecutor;
|
||||
private EntityStateHandler entityStateHandler;
|
||||
|
||||
|
||||
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
|
||||
@@ -128,33 +128,16 @@ public class GraphDatabaseContext {
|
||||
S state = getPersistentState(entity);
|
||||
return getTypeRepresentationStrategy(state, targetType).projectEntity(state, targetType);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends PropertyContainer> S getPersistentState(Object entity) {
|
||||
if (entity instanceof PropertyContainer) {
|
||||
return (S) entity;
|
||||
}
|
||||
if (isManaged(entity)) {
|
||||
return ((ManagedEntity<S>)entity).getPersistentState();
|
||||
}
|
||||
final Class<?> type = entity.getClass();
|
||||
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
|
||||
return (S)persistentEntity.getPersistentState(entity,this);
|
||||
return entityStateHandler.getPersistentState(entity);
|
||||
}
|
||||
|
||||
// todo depending on type of mapping
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends PropertyContainer> void setPersistentState(Object entity, S state) {
|
||||
if (entity instanceof PropertyContainer) {
|
||||
return;
|
||||
}
|
||||
if (isManaged(entity)) {
|
||||
((ManagedEntity<S>)entity).setPersistentState(state);
|
||||
return;
|
||||
}
|
||||
final Class<?> type = entity.getClass();
|
||||
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
|
||||
persistentEntity.setPersistentState(entity,state);
|
||||
entityStateHandler.setPersistentState(entity, state);
|
||||
}
|
||||
|
||||
public <S extends PropertyContainer, T> void postEntityCreation(S node, Class<T> entityClass) {
|
||||
@@ -163,8 +146,7 @@ public class GraphDatabaseContext {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Iterable<T> findAllByTraversal(Object entity, Class<?> targetType, TraversalDescription traversalDescription) {
|
||||
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(entity.getClass());
|
||||
final PropertyContainer state = persistentEntity.getPersistentState(entity, this);
|
||||
final PropertyContainer state = entityStateHandler.getPersistentState(entity);
|
||||
if (state == null) throw new IllegalStateException("No node attached to " + this);
|
||||
final Traverser traverser = traversalDescription.traverse((Node) state);
|
||||
if (Node.class.isAssignableFrom(targetType)) return (Iterable<T>) traverser.nodes();
|
||||
@@ -317,6 +299,7 @@ public class GraphDatabaseContext {
|
||||
|
||||
public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) {
|
||||
this.graphDatabaseService = graphDatabaseService;
|
||||
this.cypherQueryExecutor = new CypherQueryExecutor(this);
|
||||
}
|
||||
|
||||
public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy() {
|
||||
@@ -373,8 +356,8 @@ public class GraphDatabaseContext {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isManaged(Object entity) {
|
||||
return entity instanceof ManagedEntity;
|
||||
public boolean isManaged(Object entity) {
|
||||
return entityStateHandler.isManaged(entity);
|
||||
}
|
||||
|
||||
public void setConverter(Neo4jNodeConverter converter) {
|
||||
@@ -383,14 +366,19 @@ public class GraphDatabaseContext {
|
||||
|
||||
public Object executeQuery(Object entity, String queryString, Map<String, Object> params, Neo4jPersistentProperty property) {
|
||||
final TypeInformation<?> typeInformation = property.getTypeInformation();
|
||||
final Class<?> targetType = typeInformation.getActualType().getType();
|
||||
final TypeInformation<?> actualType = typeInformation.getActualType();
|
||||
final Class<?> targetType = actualType.getType();
|
||||
if (actualType.isMap()) {
|
||||
return cypherQueryExecutor.queryForList(queryString, params);
|
||||
}
|
||||
if (typeInformation.isCollectionLike()) {
|
||||
return executor.query(queryString, targetType, params);
|
||||
return cypherQueryExecutor.query(queryString, targetType, params);
|
||||
}
|
||||
if (typeInformation.isMap()) {
|
||||
return executor.queryForList(queryString, params);
|
||||
}
|
||||
return executor.queryForObject(queryString, targetType, params);
|
||||
return cypherQueryExecutor.queryForObject(queryString, targetType, params);
|
||||
}
|
||||
|
||||
public void setEntityStateHandler(EntityStateHandler entityStateHandler) {
|
||||
this.entityStateHandler = entityStateHandler;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,16 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.neo4j.support;
|
||||
|
||||
import org.neo4j.graphdb.PropertyContainer;
|
||||
import org.springframework.data.neo4j.core.EntityState;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 02.10.11
|
||||
*/
|
||||
public interface ManagedEntity<S> {
|
||||
<T extends S> T persist();
|
||||
public interface ManagedEntity<S,T> {
|
||||
<U extends T> U persist();
|
||||
|
||||
S getPersistentState();
|
||||
|
||||
EntityState<S> getEntityState();
|
||||
|
||||
void setPersistentState(S state);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
package org.springframework.data.neo4j.support.node;
|
||||
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.support.AbstractConstructorEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.EntityStateHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -31,10 +30,10 @@ import org.springframework.data.neo4j.support.AbstractConstructorEntityInstantia
|
||||
*/
|
||||
public class NodeEntityInstantiator extends AbstractConstructorEntityInstantiator<Node> {
|
||||
|
||||
private final Neo4jMappingContext mappingContext;
|
||||
private final EntityStateHandler entityStateHandler;
|
||||
|
||||
public NodeEntityInstantiator(Neo4jMappingContext mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
public NodeEntityInstantiator(EntityStateHandler entityStateHandler) {
|
||||
this.entityStateHandler = entityStateHandler;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +43,7 @@ public class NodeEntityInstantiator extends AbstractConstructorEntityInstantiato
|
||||
}
|
||||
|
||||
protected void setPersistentState(Object entity, Node node) {
|
||||
this.mappingContext.setPersistentState(entity,node);
|
||||
this.entityStateHandler.setPersistentState(entity,node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.data.neo4j.fieldaccess.DefaultEntityState;
|
||||
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.data.neo4j.support.ManagedEntity;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
@@ -65,7 +66,9 @@ public class NodeEntityState extends DefaultEntityState<Node> {
|
||||
|
||||
@Override
|
||||
public void setPersistentState(Node node) {
|
||||
graphDatabaseContext.setPersistentState(entity,node);
|
||||
if (!(entity instanceof ManagedEntity)) {
|
||||
graphDatabaseContext.setPersistentState(entity, node);
|
||||
}
|
||||
super.setPersistentState(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
package org.springframework.data.neo4j.support.relationship;
|
||||
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.support.AbstractConstructorEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.EntityStateHandler;
|
||||
import sun.reflect.ReflectionFactory;
|
||||
|
||||
/**
|
||||
@@ -30,15 +29,15 @@ import sun.reflect.ReflectionFactory;
|
||||
|
||||
public class RelationshipEntityInstantiator extends AbstractConstructorEntityInstantiator<Relationship> {
|
||||
|
||||
private final Neo4jMappingContext mappingContext;
|
||||
private final EntityStateHandler entityStateHandler;
|
||||
|
||||
public RelationshipEntityInstantiator(Neo4jMappingContext mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
public RelationshipEntityInstantiator(EntityStateHandler entityStateHandler) {
|
||||
this.entityStateHandler = entityStateHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setState(Object entity, Relationship relationship) {
|
||||
this.mappingContext.setPersistentState(entity,relationship);
|
||||
this.entityStateHandler.setPersistentState(entity,relationship);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.data.neo4j.Person;
|
||||
import org.springframework.data.neo4j.Personality;
|
||||
import org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean;
|
||||
import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
|
||||
import org.springframework.data.neo4j.support.EntityStateHandler;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseContext;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
|
||||
@@ -63,10 +64,13 @@ public class Neo4jNodeConverterTest {
|
||||
|
||||
private GraphDatabaseContext createContext(Neo4jMappingContext mappingContext) throws Exception {
|
||||
GraphDatabaseContext gdc = new GraphDatabaseContext();
|
||||
gdc.setGraphDatabaseService(new ImpermanentGraphDatabase());
|
||||
final ImpermanentGraphDatabase gdb = new ImpermanentGraphDatabase();
|
||||
gdc.setGraphDatabaseService(gdb);
|
||||
gdc.setMappingContext(mappingContext);
|
||||
gdc.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy(new NodeEntityInstantiator(mappingContext)));
|
||||
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, gdb);
|
||||
gdc.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy(new NodeEntityInstantiator(entityStateHandler)));
|
||||
gdc.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
|
||||
gdc.setEntityStateHandler(entityStateHandler);
|
||||
return gdc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user