refactored setup of Neo4jTemplate to be contained in a separate MappingInfrastructure class some steps of detangling dependencies

This commit is contained in:
Michael Hunger
2011-10-17 12:10:04 +02:00
parent 3013bebb47
commit 9a93a63cbd
30 changed files with 660 additions and 407 deletions

View File

@@ -28,15 +28,7 @@ import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.graphdb.traversal.Traverser;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.GraphTraversal;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.aspects.core.NodeBacked;
import org.springframework.data.neo4j.aspects.core.RelationshipBacked;
@@ -186,17 +178,17 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
}
public <T> Iterable<T> NodeBacked.findAllByQuery(final String query, final Class<T> targetType, Map<String,Object> params) {
final CypherQueryExecutor executor = new CypherQueryExecutor(template());
final CypherQueryExecutor executor = new CypherQueryExecutor(template().queryEngineFor(QueryType.Cypher));
return executor.query(query, targetType,params);
}
public Iterable<Map<String,Object>> NodeBacked.findAllByQuery(final String query,Map<String,Object> params) {
final CypherQueryExecutor executor = new CypherQueryExecutor(template());
final CypherQueryExecutor executor = new CypherQueryExecutor(template().queryEngineFor(QueryType.Cypher));
return executor.queryForList(query,params);
}
public <T> T NodeBacked.findByQuery(final String query, final Class<T> targetType,Map<String,Object> params) {
final CypherQueryExecutor executor = new CypherQueryExecutor(template());
final CypherQueryExecutor executor = new CypherQueryExecutor(template().queryEngineFor(QueryType.Cypher));
return executor.queryForObject(query, targetType,params);
}

View File

@@ -92,10 +92,11 @@ public class QueryEngineTest extends EntityTestBase {
assertEquals(asList(getNodeState(testTeam.emil)),result);
}
@SuppressWarnings("unchecked")
@Test
public void testQueryListOfTypePerson() throws Exception {
final String queryString = "start person=node:name_index(name={name}) match (person) <-[:boss]- (boss) return boss";
final Collection<Person> result = IteratorUtil.asCollection(queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter(template)));
final Collection<Person> result = IteratorUtil.asCollection(queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter(conversionService, template)));
assertEquals(asList(testTeam.emil),result);
}
@@ -107,7 +108,7 @@ public class QueryEngineTest extends EntityTestBase {
@Test
public void testQuerySingleOfTypePerson() throws Exception {
final String queryString = "start person=node:name_index(name={name}) match (person) <-[:boss]- (boss) return boss";
final Person result = queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter<Map<String,Object>,Person>(template)).single();
final Person result = queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter<Map<String,Object>,Person>(conversionService, template)).single();
assertEquals(testTeam.emil,result);
}

View File

@@ -30,7 +30,9 @@
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown" scope="singleton"/>
<bean id="conversionService" class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
<bean id="template" class="org.springframework.data.neo4j.support.Neo4jTemplate" init-method="postConstruct">
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructure">
<property name="graphDatabaseService" ref="graphDatabaseService"/>
<property name="conversionService" ref="conversionService"/>
<property name="mappingContext" ref="mappingContext"/>
@@ -43,12 +45,15 @@
<property name="relationshipTypeRepresentationStrategy" ref="relationshipTypeRepresentationStrategy"/>
<property name="relationshipEntityStateFactory" ref="relationshipEntityStateFactory"/>
<property name="relationshipEntityInstantiator" ref="relationshipEntityInstantiator"/>
<property name="validator">
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
</property>
</bean>
<bean id="template" class="org.springframework.data.neo4j.support.Neo4jTemplate" init-method="postConstruct">
<property name="infrastructure" ref="mappingInfrastructure"/>
</bean>
<bean id="entityStateHandler" class="org.springframework.data.neo4j.support.EntityStateHandler">
<constructor-arg ref="mappingContext"/>

View File

@@ -90,7 +90,7 @@
<constructor-arg ref="graphDatabaseService"/>
</bean>
<bean id="neo4jTemplate" class="org.springframework.data.neo4j.support.Neo4jTemplate">
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructure">
<property name="graphDatabaseService" ref="graphDatabaseService"/>
<property name="conversionService">
<bean class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
@@ -102,6 +102,10 @@
<property name="graphDatabase" ref="graphDatabase"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<bean id="neo4jTemplate" class="org.springframework.data.neo4j.support.Neo4jTemplate">
<property name="infrastructure" ref="mappingInfrastructure"/>
</bean>
<bean id="graphEntityInstantiator" class="org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityInstantiator">
<constructor-arg ref="nodeEntityInstantiator"/>
<constructor-arg ref="entityManagerFactory"/>

View File

@@ -38,6 +38,8 @@ import java.util.Map;
public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDatabase implements GraphDatabase{
private ConversionService conversionService;
private ResultConverter resultConverter;
public SpringRestGraphDatabase( RestAPI api){
super(api);
}
@@ -100,8 +102,13 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
}
private ResultConverter createResultConverter() {
if (conversionService==null) return new DefaultConverter();
return new ConversionServiceQueryResultConverter(conversionService);
if (resultConverter!=null) return resultConverter;
if (conversionService != null) {
this.resultConverter = new ConversionServiceQueryResultConverter(conversionService);
} else {
this.resultConverter = new DefaultConverter();
}
return resultConverter;
}
private static class SpringResultConverter implements org.neo4j.rest.graphdb.util.ResultConverter {
@@ -112,6 +119,7 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
}
@Override
@SuppressWarnings("unchecked")
public Object convert(Object value, Class target) {
return resultConverter.convert(value,target);
}
@@ -134,6 +142,12 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
relationship.delete();
}
@Override
public void setResultConverter(ResultConverter resultConverter) {
}
private void removeFromIndexes(Node node) {
final RestIndexManager indexManager = index();
for (String indexName : indexManager.nodeIndexNames()) {

View File

@@ -18,16 +18,17 @@ package org.springframework.data.neo4j.config;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import javax.annotation.PostConstruct;
/**
* Validates correct configuration of Neo4j and Spring, especially transaction-managers
*/
public class ConfigurationCheck {
public class ConfigurationCheck implements ApplicationListener<ContextStartedEvent> {
Neo4jTemplate template;
PlatformTransactionManager transactionManager;
@@ -36,7 +37,12 @@ public class ConfigurationCheck {
this.transactionManager = transactionManager;
}
@PostConstruct
@Override
public void onApplicationEvent(ContextStartedEvent event) {
checkConfiguration();
}
//@PostConstruct
private void checkConfiguration() {
checkInjection();
checkSpringTransactionManager();
@@ -44,7 +50,9 @@ public class ConfigurationCheck {
}
private void checkInjection() {
assert template.getGraphDatabaseService()!=null : "graphDatabaseService not correctly configured, please refer to the manual, setup section";
if (template.getGraphDatabaseService()==null) {
throw new BeanCreationException("graphDatabaseService not correctly configured, please refer to the manual, setup section");
}
}
private void checkSpringTransactionManager() {
@@ -53,9 +61,7 @@ public class ConfigurationCheck {
updateStartTime();
transactionManager.commit(transaction);
} catch(Exception e) {
AssertionError error = new AssertionError("transactionManager not correctly configured, please refer to the manual, setup section");
error.initCause(e);
throw error;
throw new BeanCreationException("transactionManager not correctly configured, please refer to the manual, setup section",e);
}
}
@@ -66,9 +72,7 @@ public class ConfigurationCheck {
updateStartTime();
tx.success();
} catch (Exception e) {
AssertionError error = new AssertionError("transactionManager not correctly configured, please refer to the manual, setup section");
error.initCause(e);
throw error;
throw new BeanCreationException("transactionManager not correctly configured, please refer to the manual, setup section",e);
} finally {
try {
if (tx != null) tx.finish();

View File

@@ -37,10 +37,7 @@ import org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryB
import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.mapping.*;
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
import org.springframework.data.neo4j.support.EntityInstantiator;
import org.springframework.data.neo4j.support.EntityStateHandler;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.*;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
@@ -80,29 +77,34 @@ public abstract class Neo4jConfiguration {
}
@Bean
public Neo4jTemplate neo4jTemplate() throws Exception {
public MappingInfrastructure mappingInfrastructure() throws Exception {
MappingInfrastructure infrastructure = new MappingInfrastructure();
infrastructure.setGraphDatabaseService(getGraphDatabaseService());
infrastructure.setConversionService(conversionService());
infrastructure.setMappingContext(mappingContext());
infrastructure.setEntityStateHandler(entityStateHandler());
Neo4jTemplate neo4jTemplate = new Neo4jTemplate();
neo4jTemplate.setGraphDatabaseService(getGraphDatabaseService());
neo4jTemplate.setConversionService(conversionService());
neo4jTemplate.setMappingContext(mappingContext());
neo4jTemplate.setEntityStateHandler(entityStateHandler());
infrastructure.setNodeEntityStateFactory(nodeEntityStateFactory());
infrastructure.setNodeTypeRepresentationStrategy(nodeTypeRepresentationStrategy());
infrastructure.setNodeEntityInstantiator(graphEntityInstantiator());
neo4jTemplate.setNodeEntityStateFactory(nodeEntityStateFactory());
neo4jTemplate.setNodeTypeRepresentationStrategy(nodeTypeRepresentationStrategy());
neo4jTemplate.setNodeEntityInstantiator(graphEntityInstantiator());
infrastructure.setRelationshipEntityStateFactory(relationshipEntityStateFactory());
infrastructure.setRelationshipTypeRepresentationStrategy(relationshipTypeRepresentationStrategy());
infrastructure.setRelationshipEntityInstantiator(graphRelationshipInstantiator());
neo4jTemplate.setRelationshipEntityStateFactory(relationshipEntityStateFactory());
neo4jTemplate.setRelationshipTypeRepresentationStrategy(relationshipTypeRepresentationStrategy());
neo4jTemplate.setRelationshipEntityInstantiator(graphRelationshipInstantiator());
neo4jTemplate.setTransactionManager(neo4jTransactionManager());
neo4jTemplate.setGraphDatabase(graphDatabase());
infrastructure.setTransactionManager(neo4jTransactionManager());
infrastructure.setGraphDatabase(graphDatabase());
if (validator!=null) {
neo4jTemplate.setValidator(validator);
infrastructure.setValidator(validator);
}
return neo4jTemplate;
return infrastructure;
}
@Bean
public Neo4jTemplate neo4jTemplate() throws Exception {
final Neo4jTemplate neo4jTemplate = new Neo4jTemplate();
neo4jTemplate.setInfrastructure(mappingInfrastructure());
return neo4jTemplate;
}
@Bean

View File

@@ -111,4 +111,6 @@ public interface GraphDatabase {
void remove(Node node);
void remove(Relationship relationship);
void setResultConverter(ResultConverter resultConverter);
}

View File

@@ -0,0 +1,31 @@
/**
* 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.mapping;
import org.neo4j.graphdb.PropertyContainer;
/**
* @author mh
* @since 17.10.11
*/
public interface EntityPersister {
<S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType);
<S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state);
boolean isNodeEntity(Class<?> targetType);
boolean isRelationshipEntity(Class targetType);
}

View File

@@ -32,7 +32,7 @@ import java.util.Map;
* @author mh
* @since 11.10.11
*/
public class Neo4jEntityPersister implements Neo4jEntityConverter<Object,Node> {
public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConverter<Object,Node> {
Neo4jEntityConverter<Object,Node> nodeConverter;
Neo4jEntityConverter<Object,Relationship> relationshipConverter;
private EntityStateHandler entityStateHandler;

View File

@@ -31,7 +31,7 @@ import java.lang.reflect.Field;
/**
* Neo4J specific {@link MappingContext} implementation. Simply creates {@link Neo4jPersistentEntityImpl} and
* {@link Neo4jPersistentProperty} instances.
*
*
* @author Oliver Gierke
*/
public class Neo4jMappingContext extends AbstractMappingContext<Neo4jPersistentEntityImpl<?>, Neo4jPersistentProperty> {
@@ -44,21 +44,29 @@ public class Neo4jMappingContext extends AbstractMappingContext<Neo4jPersistentE
if (type.isAnnotationPresent(RelationshipEntity.class)) {
return new Neo4jPersistentEntityImpl<T>(typeInformation);
}
throw new MappingException("Type "+type+" is neither a @NodeEntity nor a @RelationshipEntity");
throw new MappingException("Type " + type + " is neither a @NodeEntity nor a @RelationshipEntity");
}
@Override
protected Neo4jPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
Neo4jPersistentEntityImpl<?> owner, SimpleTypeHolder simpleTypeHolder) {
Neo4jPersistentEntityImpl<?> owner, SimpleTypeHolder simpleTypeHolder) {
return new Neo4jPersistentPropertyImpl(field, descriptor, owner, simpleTypeHolder);
}
public boolean isNodeEntity(Class<?> type) {
return getPersistentEntity(type).isNodeEntity();
try {
return getPersistentEntity(type).isNodeEntity();
} catch (MappingException me) {
return false;
}
}
public boolean isRelationshipEntity(Class<?> type) {
return getPersistentEntity(type).isRelationshipEntity();
try {
return getPersistentEntity(type).isRelationshipEntity();
} catch (MappingException me) {
return false;
}
}
public void setPersistentState(Object entity, PropertyContainer pc) {

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.neo4j.mapping;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Transaction;
import org.springframework.data.mapping.Association;
@@ -44,7 +42,7 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
public <R> R copyPropertiesFrom(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S source, Neo4jPersistentEntity<R> persistentEntity) {
final R entity = wrapper.getBean();
final Transaction tx = getGraphDatabaseContext().beginTx();
final Transaction tx = getTemplate().beginTx();
try {
final EntityState<S> entityState = entityStateFactory.getEntityState(entity, false);
entityState.setPersistentState(source);
@@ -75,7 +73,7 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
entityState.setValue(property, value);
}
private Neo4jTemplate getGraphDatabaseContext() {
private Neo4jTemplate getTemplate() {
return entityStateFactory.getTemplate();
}
@@ -116,7 +114,7 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
}
public <R> void copyPropertiesTo(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S target, Neo4jPersistentEntity<R> persistentEntity) {
final Transaction tx = getGraphDatabaseContext().beginTx();
final Transaction tx = getTemplate().beginTx();
try {
//final Node targetNode = useGetOrCreateNode(node, persistentEntity, wrapper);
final EntityState<S> entityState = entityStateFactory.getEntityState(wrapper.getBean(), false);
@@ -141,19 +139,4 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
}
}
private Node useGetOrCreateNode(Node node, Neo4jPersistentEntity<?> persistentEntity, BeanWrapper<Neo4jPersistentEntity<Object>, Object> wrapper) {
if (node != null) return node;
final Neo4jPersistentProperty idProperty = persistentEntity.getIdProperty();
final Long id = getProperty(wrapper, idProperty, Long.class, true);
if (id == null) {
final Node newNode = getGraphDatabaseContext().createNode();
setProperty(wrapper, idProperty, newNode.getId());
return newNode;
}
try {
return getGraphDatabaseContext().getNode(id);
} catch (NotFoundException nfe) {
throw new MappingException("Could not find node with id " + id);
}
}
}

View File

@@ -25,14 +25,14 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.repository.query.DerivedCypherRepositoryQuery;
import org.springframework.data.neo4j.support.GenericTypeExtractor;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
import org.springframework.data.neo4j.support.query.GremlinQueryEngine;
import org.springframework.data.neo4j.support.query.QueryEngine;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -291,7 +291,12 @@ public class GraphRepositoryFactory extends RepositoryFactorySupport {
public CypherGraphRepositoryQuery(GraphQueryMethod queryMethod, RepositoryMetadata metadata, final Neo4jTemplate template) {
super(queryMethod, metadata, template);
queryExecutor = new CypherQueryExecutor(template);
}
private CypherQueryExecutor getQueryExecutor() {
if (this.queryExecutor!=null) return this.queryExecutor;
this.queryExecutor = new CypherQueryExecutor(getTemplate().queryEngineFor(QueryType.Cypher));
return this.queryExecutor;
}
@Override
@@ -303,27 +308,34 @@ public class GraphRepositoryFactory extends RepositoryFactorySupport {
}
if (queryMethod.isIterableResult()) {
if (compoundType.isAssignableFrom(Map.class)) {
return queryExecutor.queryForList(queryString,params);
return getQueryExecutor().queryForList(queryString, params);
}
return queryExecutor.query(queryString, queryMethod.getCompoundType(),params);
return getQueryExecutor().query(queryString, queryMethod.getCompoundType(), params);
}
return queryExecutor.queryForObject(queryString, queryMethod.getReturnType(),params);
return getQueryExecutor().queryForObject(queryString, queryMethod.getReturnType(), params);
}
private Object queryPaged(String queryString, Map<String, Object> params, Pageable pageable) {
final Iterable<?> result = queryExecutor.query(queryString, getQueryMethod().getCompoundType(),params);
final Iterable<?> result = getQueryExecutor().query(queryString, getQueryMethod().getCompoundType(), params);
return createPage(result, pageable);
}
}
private static class GremlinGraphRepositoryQuery extends GraphRepositoryQuery {
private GremlinQueryEngine queryExecutor;
private QueryEngine queryEngine;
public GremlinGraphRepositoryQuery(GraphQueryMethod queryMethod, RepositoryMetadata metadata, final Neo4jTemplate template) {
super(queryMethod, metadata, template);
queryExecutor = new GremlinQueryEngine(template.getGraphDatabaseService(), new EntityResultConverter<Object, Object>(template));
}
private QueryEngine getQueryEngine() {
if (this.queryEngine !=null) return queryEngine;
this.queryEngine = getTemplate().queryEngineFor(QueryType.Gremlin);
return this.queryEngine;
}
@SuppressWarnings("unchecked")
@Override
protected Object dispatchQuery(String queryString, Map<String, Object> params, Pageable pageable) {
GraphQueryMethod queryMethod = getQueryMethod();
@@ -331,13 +343,13 @@ public class GraphRepositoryFactory extends RepositoryFactorySupport {
return queryPaged(queryString,params,pageable);
}
if (queryMethod.isIterableResult()) {
return queryExecutor.query(queryString,params).to(queryMethod.getCompoundType());
return getQueryEngine().query(queryString, params).to(queryMethod.getCompoundType());
}
return queryExecutor.query(queryString, params).to(queryMethod.getReturnType()).single();
return getQueryEngine().query(queryString, params).to(queryMethod.getReturnType()).single();
}
private Object queryPaged(String queryString, Map<String, Object> params, Pageable pageable) {
final Iterable<?> result = queryExecutor.query(queryString, params).to(getQueryMethod().getCompoundType());
@SuppressWarnings("unchecked") final Iterable<?> result = getQueryEngine().query(queryString, params).to(getQueryMethod().getCompoundType());
return createPage(result, pageable);
}
@@ -352,6 +364,10 @@ public class GraphRepositoryFactory extends RepositoryFactorySupport {
this.template = template;
}
protected Neo4jTemplate getTemplate() {
return template;
}
@Override
public Object execute(Object[] parameters) {
Map<String, Object> params = queryMethod.resolveParams(parameters, template);

View File

@@ -21,6 +21,7 @@ import java.util.Map;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.repository.GraphRepositoryFactory.GraphQueryMethod;
@@ -64,7 +65,7 @@ public class DerivedCypherRepositoryQuery implements RepositoryQuery {
this.query = new CypherQueryCreator(tree, context, info.getJavaType()).createQuery();
this.method = method;
this.executor = new CypherQueryExecutor(database);
this.executor = new CypherQueryExecutor(database.queryEngineFor(QueryType.Cypher));
}
/*

View File

@@ -27,6 +27,7 @@ import org.neo4j.kernel.AbstractGraphDatabase;
import org.neo4j.kernel.Traversal;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.conversion.DefaultConverter;
import org.springframework.data.neo4j.conversion.Result;
import org.springframework.data.neo4j.conversion.ResultConverter;
import org.springframework.data.neo4j.core.GraphDatabase;
@@ -66,6 +67,11 @@ public class DelegatingGraphDatabase implements GraphDatabase {
this.conversionService = conversionService;
}
@Override
public void setResultConverter(ResultConverter resultConverter) {
this.resultConverter = resultConverter;
}
@Override
public Node getNodeById(long id) {
return delegate.getNodeById(id);
@@ -217,8 +223,10 @@ public class DelegatingGraphDatabase implements GraphDatabase {
if (resultConverter!=null) return resultConverter;
if (conversionService != null) {
this.resultConverter = new ConversionServiceQueryResultConverter(conversionService);
} else {
this.resultConverter = new DefaultConverter();
}
return null;
return resultConverter;
}
public void shutdown() {

View File

@@ -0,0 +1,89 @@
/**
* 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.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.index.Index;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntityImpl;
import static org.springframework.data.neo4j.support.ParameterCheck.notNull;
/**
* @author mh
* @since 17.10.11
*/
class IndexProvider {
private Neo4jMappingContext mappingContext;
private final GraphDatabase graphDatabase;
IndexProvider(Neo4jMappingContext mappingContext, GraphDatabase graphDatabase) {
this.mappingContext = mappingContext;
this.graphDatabase = graphDatabase;
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
return getIndex(type, null);
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
return getIndex(type, indexName, null);
}
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName, Boolean fullText) {
if (type == null) {
notNull(indexName, "indexName");
return getIndex(indexName);
}
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
if (indexName == null) indexName = Indexed.Name.get(type);
final boolean useExistingIndex = fullText == null;
if (useExistingIndex) {
if (persistentEntity.isNodeEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
if (persistentEntity.isRelationshipEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}
if (persistentEntity.isNodeEntity()) return (Index<S>) createIndex(Node.class, indexName, fullText);
if (persistentEntity.isRelationshipEntity())
return (Index<S>) createIndex(Relationship.class, indexName, fullText);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
return graphDatabase.getIndex(indexName);
}
public boolean isNode(Class<? extends PropertyContainer> type) {
if (type.equals(Node.class)) return true;
if (type.equals(Relationship.class)) return false;
throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship" + type);
}
// TODO handle existing indexes
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, boolean fullText) {
return graphDatabase.createIndex(type, indexName, fullText);
}
}

View File

@@ -0,0 +1,216 @@
/**
* 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.Node;
import org.neo4j.graphdb.Relationship;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.conversion.ResultConverter;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.core.TypeRepresentationStrategy;
import org.springframework.data.neo4j.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.node.EntityStateFactory;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
import org.springframework.data.neo4j.support.typerepresentation.NoopNodeTypeRepresentationStrategy;
import org.springframework.data.neo4j.support.typerepresentation.NoopRelationshipTypeRepresentationStrategy;
import org.springframework.transaction.PlatformTransactionManager;
import javax.validation.Validator;
/**
* @author mh
* @since 17.10.11
*/
public class MappingInfrastructure {
private ConversionService conversionService;
private Validator validator;
private TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy;
private TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy;
private Neo4jMappingContext mappingContext;
private CypherQueryExecutor cypherQueryExecutor;
private EntityStateHandler entityStateHandler;
private Neo4jEntityPersister entityPersister;
private EntityStateFactory<Node> nodeEntityStateFactory;
private EntityStateFactory<Relationship> relationshipEntityStateFactory;
private EntityRemover entityRemover;
private TypeRepresentationStrategies typeRepresentationStrategies;
private EntityInstantiator<Relationship> relationshipEntityInstantiator;
private EntityInstantiator<Node> nodeEntityInstantiator;
private PlatformTransactionManager transactionManager;
private ResultConverter resultConverter;
private IndexProvider indexProvider;
private GraphDatabaseService graphDatabaseService;
private GraphDatabase graphDatabase;
public MappingInfrastructure(GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
this.graphDatabase = graphDatabase;
this.transactionManager = transactionManager;
}
public MappingInfrastructure() {
}
// @PostConstruct // TODO
public void postConstruct() {
if (this.mappingContext == null) this.mappingContext = new Neo4jMappingContext();
if (this.graphDatabase == null) {
this.graphDatabase = new DelegatingGraphDatabase(graphDatabaseService);
}
if (nodeEntityInstantiator == null) {
nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler);
}
if (relationshipEntityInstantiator == null) {
relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler);
}
if (this.nodeTypeRepresentationStrategy == null)
this.nodeTypeRepresentationStrategy = new NoopNodeTypeRepresentationStrategy(nodeEntityInstantiator);
if (this.relationshipTypeRepresentationStrategy == null)
this.relationshipTypeRepresentationStrategy = new NoopRelationshipTypeRepresentationStrategy(relationshipEntityInstantiator);
this.typeRepresentationStrategies = new TypeRepresentationStrategies(mappingContext, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
EntityTools<Node> nodeEntityTools = new EntityTools<Node>(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator);
EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator);
this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, graphDatabase);
this.indexProvider = new IndexProvider(mappingContext, graphDatabase);
if (this.resultConverter==null) {
this.resultConverter = new EntityResultConverter<Object, Object>(conversionService,entityPersister);
}
this.graphDatabase.setResultConverter(resultConverter);
this.cypherQueryExecutor = new CypherQueryExecutor(graphDatabase.queryEngineFor(QueryType.Cypher, resultConverter));
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void setRelationshipEntityInstantiator(EntityInstantiator<Relationship> relationshipEntityInstantiator) {
this.relationshipEntityInstantiator = relationshipEntityInstantiator;
}
public void setNodeEntityInstantiator(EntityInstantiator<Node> nodeEntityInstantiator) {
this.nodeEntityInstantiator = nodeEntityInstantiator;
}
public void setEntityStateHandler(EntityStateHandler entityStateHandler) {
this.entityStateHandler = entityStateHandler;
}
public void setNodeEntityStateFactory(EntityStateFactory<Node> nodeEntityStateFactory) {
this.nodeEntityStateFactory = nodeEntityStateFactory;
}
public void setRelationshipEntityStateFactory(EntityStateFactory<Relationship> relationshipEntityStateFactory) {
this.relationshipEntityStateFactory = relationshipEntityStateFactory;
}
public EntityStateHandler getEntityStateHandler() {
return entityStateHandler;
}
public TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy() {
return nodeTypeRepresentationStrategy;
}
public void setNodeTypeRepresentationStrategy(TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy) {
this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy;
}
public TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy() {
return relationshipTypeRepresentationStrategy;
}
public void setRelationshipTypeRepresentationStrategy(TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy) {
this.relationshipTypeRepresentationStrategy = relationshipTypeRepresentationStrategy;
}
public ConversionService getConversionService() {
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public Validator getValidator() {
return validator;
}
public void setValidator(Validator validatorFactory) {
this.validator = validatorFactory;
}
public void setMappingContext(Neo4jMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
public GraphDatabaseService getGraphDatabaseService() {
return graphDatabaseService;
}
public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) {
this.graphDatabaseService = graphDatabaseService;
}
public void setGraphDatabase(GraphDatabase graphDatabase) {
this.graphDatabase = graphDatabase;
}
public GraphDatabase getGraphDatabase() {
return graphDatabase;
}
public ResultConverter getResultConverter() {
return resultConverter;
}
public EntityRemover getEntityRemover() {
return entityRemover;
}
public IndexProvider getIndexProvider() {
return indexProvider;
}
public Neo4jEntityPersister getEntityPersister() {
return entityPersister;
}
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public TypeRepresentationStrategies getTypeRepresentationStrategies() {
return typeRepresentationStrategies;
}
public CypherQueryExecutor getCypherQueryExecutor() {
return cypherQueryExecutor;
}
}

View File

@@ -25,7 +25,6 @@ import org.neo4j.helpers.collection.ClosableIterable;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
@@ -35,18 +34,11 @@ import org.springframework.data.neo4j.conversion.ResultConverter;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.core.TypeRepresentationStrategy;
import org.springframework.data.neo4j.core.UncategorizedGraphStoreException;
import org.springframework.data.neo4j.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntityImpl;
import org.springframework.data.neo4j.mapping.EntityPersister;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.NodeGraphRepository;
import org.springframework.data.neo4j.repository.RelationshipGraphRepository;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.node.EntityStateFactory;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
import org.springframework.data.neo4j.support.query.QueryEngine;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
import org.springframework.data.neo4j.template.GraphCallback;
import org.springframework.data.neo4j.template.Neo4jExceptionTranslator;
import org.springframework.data.neo4j.template.Neo4jOperations;
@@ -62,6 +54,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import static org.springframework.data.neo4j.support.ParameterCheck.notNull;
/**
* Mediator class for the graph related services like the {@link GraphDatabaseService}, the used
* {@link org.springframework.data.neo4j.core.TypeRepresentationStrategy}, entity instantiators for nodes and relationships as well as a spring conversion service.
@@ -71,37 +65,19 @@ import java.util.Map;
* @author Michael Hunger
* @since 13.09.2010
*/
public class Neo4jTemplate implements Neo4jOperations {
/*
TODO This is a merge of GraphDatabaseContext and the previous Neo4jTemplate, so it still contains inconsistencies, if you spot them, please mark them with a TODO
*/
public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
private static final Log log = LogFactory.getLog(Neo4jTemplate.class);
private GraphDatabaseService graphDatabaseService;
private ConversionService conversionService;
private Validator validator;
private TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy;
private TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy;
private Neo4jMappingContext mappingContext;
private CypherQueryExecutor cypherQueryExecutor;
private EntityStateHandler entityStateHandler;
private Neo4jEntityPersister entityPersister;
private EntityStateFactory<Node> nodeEntityStateFactory;
private EntityStateFactory<Relationship> relationshipEntityStateFactory;
private EntityRemover entityRemover;
private TypeRepresentationStrategies typeRepresentationStrategies;
private EntityInstantiator<Relationship> relationshipEntityInstantiator;
private EntityInstantiator<Node> nodeEntityInstantiator;
private PlatformTransactionManager transactionManager;
private GraphDatabase graphDatabase;
private ResultConverter resultConverter;
private IndexProvider indexProvider;
private MappingInfrastructure infrastructure = new MappingInfrastructure();
/**
* default constructor for dependency injection, TODO provide dependencies at creation time
*/
public Neo4jTemplate() {
this.infrastructure = new MappingInfrastructure();
}
/**
@@ -110,14 +86,16 @@ public class Neo4jTemplate implements Neo4jOperations {
*/
public Neo4jTemplate(final GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
notNull(graphDatabase, "graphDatabase");
this.transactionManager = transactionManager;
this.graphDatabase = graphDatabase;
this.infrastructure = new MappingInfrastructure(graphDatabase,transactionManager);
}
public Neo4jTemplate(final GraphDatabase graphDatabase) {
notNull(graphDatabase, "graphDatabase");
transactionManager = null;
this.graphDatabase = graphDatabase;
this.infrastructure = new MappingInfrastructure(graphDatabase,null);
}
public Neo4jTemplate(MappingInfrastructure infrastructure) {
this.infrastructure = infrastructure;
}
@@ -128,140 +106,78 @@ public class Neo4jTemplate implements Neo4jOperations {
throw new IllegalArgumentException("Can't create graph repository for non graph entity of type " + clazz);
}
public GraphDatabase getGraphDatabase() {
return graphDatabase;
}
static class IndexProvider {
private Neo4jMappingContext mappingContext;
private final GraphDatabase graphDatabase;
IndexProvider(Neo4jMappingContext mappingContext, GraphDatabase graphDatabase) {
this.mappingContext = mappingContext;
this.graphDatabase = graphDatabase;
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
return getIndex(type, null);
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
return getIndex(type, indexName, null);
}
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName, Boolean fullText) {
if (type == null) {
notNull(indexName, "indexName");
return getIndex(indexName);
}
final Neo4jPersistentEntityImpl<?> persistentEntity = mappingContext.getPersistentEntity(type);
if (indexName == null) indexName = Indexed.Name.get(type);
final boolean useExistingIndex = fullText == null;
if (useExistingIndex) {
if (persistentEntity.isNodeEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
if (persistentEntity.isRelationshipEntity()) return (Index<S>) graphDatabase.getIndex(indexName);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}
if (persistentEntity.isNodeEntity()) return (Index<S>) createIndex(Node.class, indexName, fullText);
if (persistentEntity.isRelationshipEntity())
return (Index<S>) createIndex(Relationship.class, indexName, fullText);
throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity");
}
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
return graphDatabase.getIndex(indexName);
}
public boolean isNode(Class<? extends PropertyContainer> type) {
if (type.equals(Node.class)) return true;
if (type.equals(Relationship.class)) return false;
throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship" + type);
}
// TODO handle existing indexes
@SuppressWarnings("unchecked")
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, boolean fullText) {
return graphDatabase.createIndex(type, indexName, fullText);
}
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
return indexProvider.getIndex(type, null);
return infrastructure.getIndexProvider().getIndex(type, null);
}
public <S extends PropertyContainer> Index<S> getIndex(String name) {
return indexProvider.getIndex(null, name);
return infrastructure.getIndexProvider().getIndex(null, name);
}
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
return indexProvider.getIndex(type, indexName, null);
return infrastructure.getIndexProvider().getIndex(type, indexName, null);
}
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName, Boolean fullText) {
return indexProvider.getIndex(type, indexName, fullText);
return infrastructure.getIndexProvider().getIndex(type, indexName, fullText);
}
/**
* @return true if a transaction manager is available and a transaction is currently running
*/
public boolean transactionIsRunning() {
return graphDatabase.transactionIsRunning();
return infrastructure.getGraphDatabase().transactionIsRunning();
}
public <T> ClosableIterable<T> findAll(final Class<T> entityClass) {
return typeRepresentationStrategies.findAll(entityClass);
return infrastructure.getTypeRepresentationStrategies().findAll(entityClass);
}
public <T> long count(final Class<T> entityClass) {
return typeRepresentationStrategies.count(entityClass);
return infrastructure.getTypeRepresentationStrategies().count(entityClass);
}
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state) {
return entityPersister.createEntityFromStoredType(state);
return infrastructure.getEntityPersister().createEntityFromStoredType(state);
}
public <S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type) {
return entityPersister.createEntityFromState(state, type);
return infrastructure.getEntityPersister().createEntityFromState(state, type);
}
public <S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType) {
return entityPersister.projectTo(entity, targetType);
return infrastructure.getEntityPersister().projectTo(entity, targetType);
}
@SuppressWarnings("unchecked")
public <S extends PropertyContainer> S getPersistentState(Object entity) {
return entityPersister.getPersistentState(entity);
return infrastructure.getEntityPersister().getPersistentState(entity);
}
// todo depending on type of mapping
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> T setPersistentState(T entity, S state) {
entityPersister.setPersistentState(entity, state);
infrastructure.getEntityPersister().setPersistentState(entity, state);
return entity;
}
@Deprecated() // TODO remove
public <S extends PropertyContainer, T> void postEntityCreation(S node, Class<T> entityClass) {
typeRepresentationStrategies.postEntityCreation(node, entityClass);
infrastructure.getTypeRepresentationStrategies().postEntityCreation(node, entityClass);
}
public void remove(Object entity) {
entityRemover.remove(entity);
infrastructure.getEntityRemover().remove(entity);
}
public void removeNodeEntity(Object entity) {
entityRemover.removeNodeEntity(entity);
infrastructure.getEntityRemover().removeNodeEntity(entity);
}
public void removeRelationshipEntity(Object entity) {
entityRemover.removeRelationshipEntity(entity);
infrastructure.getEntityRemover().removeRelationshipEntity(entity);
}
/**
@@ -269,18 +185,18 @@ public class Neo4jTemplate implements Neo4jOperations {
*/
@Override
public Node createNode() {
return graphDatabase.createNode(null);
return infrastructure.getGraphDatabase().createNode(null);
}
@Override
public Node createNode(final Map<String, Object> properties) {
return graphDatabase.createNode(properties);
return infrastructure.getGraphDatabase().createNode(properties);
}
public <T> T createNode(Class<T> target, Map<String, Object> properties) {
final Node node = createNode(properties);
if (isNodeEntity(target)) {
typeRepresentationStrategies.postEntityCreation(node, target);
infrastructure.getTypeRepresentationStrategies().postEntityCreation(node, target);
}
return convert(node, target);
}
@@ -295,7 +211,7 @@ public class Neo4jTemplate implements Neo4jOperations {
}
public <T> Iterable<T> createNodes(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy = isNodeEntity(target) ? typeRepresentationStrategies.getNodeTypeRepresentationStrategy() : null;
final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy = isNodeEntity(target) ? infrastructure.getTypeRepresentationStrategies().getNodeTypeRepresentationStrategy() : null;
Collection<Node> result = new ArrayList<Node>(otherNodes.length + 1);
result.add(createNode(firstNode, target, nodeTypeRepresentationStrategy));
for (Map<String, Object> properties : otherNodes) {
@@ -316,29 +232,12 @@ public class Neo4jTemplate implements Neo4jOperations {
* Delegates to {@link GraphDatabaseService}
*/
public Transaction beginTx() { // todo remove !
return graphDatabaseService.beginTx();
return infrastructure.getGraphDatabaseService().beginTx();
}
@PostConstruct
public Neo4jTemplate postConstruct() {
this.resultConverter = new EntityResultConverter<Object, Object>(this);
if (this.graphDatabase == null) {
this.graphDatabase = new DelegatingGraphDatabase(graphDatabaseService, resultConverter);
}
this.typeRepresentationStrategies = new TypeRepresentationStrategies(mappingContext, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy);
this.cypherQueryExecutor = new CypherQueryExecutor(this);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
if (nodeEntityInstantiator == null) {
nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler);
}
EntityTools<Node> nodeEntityTools = new EntityTools<Node>(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator);
if (relationshipEntityInstantiator == null) {
relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler);
}
EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator);
this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, graphDatabase);
this.indexProvider = new IndexProvider(mappingContext, graphDatabase);
infrastructure.postConstruct();
return this;
}
@@ -353,42 +252,45 @@ public class Neo4jTemplate implements Neo4jOperations {
@SuppressWarnings("unchecked")
public <T> T save(T entity) {
return (T) entityPersister.persist(entity);
return (T) infrastructure.getEntityPersister().persist(entity);
}
public boolean isManaged(Object entity) {
return entityStateHandler.isManaged(entity);
return infrastructure.getEntityStateHandler().isManaged(entity);
}
public Object query(String statement, Map<String, Object> params, final TypeInformation<?> typeInformation) {
final TypeInformation<?> actualType = typeInformation.getActualType();
final Class<?> targetType = actualType.getType();
if (actualType.isMap()) {
return cypherQueryExecutor.queryForList(statement, params);
return infrastructure.getCypherQueryExecutor().queryForList(statement, params);
}
if (typeInformation.isCollectionLike()) {
return cypherQueryExecutor.query(statement, targetType, params);
return infrastructure.getCypherQueryExecutor().query(statement, targetType, params);
}
return cypherQueryExecutor.queryForObject(statement, targetType, params);
return infrastructure.getCypherQueryExecutor().queryForObject(statement, targetType, params);
}
public <R> R getRelationshipBetween(Object source, Object target, Class<R> relationshipClass, String type) {
final Relationship relationship = entityStateHandler.getRelationshipTo(source, target, type);
public <R> R getRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType) {
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
final Relationship relationship = infrastructure.getEntityStateHandler().getRelationshipTo(start, end, relationshipType);
if (relationship == null) return null;
return entityPersister.createEntityFromState(relationship, relationshipClass);
return infrastructure.getEntityPersister().createEntityFromState(relationship, relationshipEntityClass);
}
public void removeRelationshipBetween(Object start, Object target, String type) {
entityRemover.removeRelationshipTo(start, target, type);
public void removeRelationshipBetween(Object start, Object end, String type) {
notNull(start,"start",end,"end",type,"relationshipType");
infrastructure.getEntityRemover().removeRelationshipTo(start, end, type);
}
public <R> R createRelationshipBetween(Object source, Object target, Class<R> relationshipClass, String relationshipType, boolean allowDuplicates) {
final RelationshipResult result = entityStateHandler.relateTo(source, target, relationshipType, allowDuplicates);
public <R> R createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates) {
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
final RelationshipResult result = infrastructure.getEntityStateHandler().relateTo(start, end, relationshipType, allowDuplicates);
if (result.type == RelationshipResult.Type.NEW) {
// TODO
postEntityCreation(result.relationship, relationshipClass);
postEntityCreation(result.relationship, relationshipEntityClass);
}
return createEntityFromState(result.relationship, relationshipClass);
return createEntityFromState(result.relationship, relationshipEntityClass);
}
@Override
@@ -404,15 +306,6 @@ public class Neo4jTemplate implements Neo4jOperations {
private final Neo4jExceptionTranslator exceptionTranslator = new Neo4jExceptionTranslator();
private static void notNull(Object... pairs) {
assert pairs.length % 2 == 0 : "wrong number of pairs to check";
for (int i = 0; i < pairs.length; i += 2) {
if (pairs[i] == null) {
throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + pairs[i + 1] + " is required; it must not be null");
}
}
}
public DataAccessException translateExceptionIfPossible(Exception ex) {
if (ex instanceof RuntimeException) {
return exceptionTranslator.translateExceptionIfPossible((RuntimeException) ex);
@@ -424,7 +317,7 @@ public class Neo4jTemplate implements Neo4jOperations {
private <T> T doExecute(final GraphCallback<T> callback) {
notNull(callback, "callback");
try {
return callback.doWithGraph(graphDatabase);
return callback.doWithGraph(infrastructure.getGraphDatabase());
} catch (Exception e) {
throw translateExceptionIfPossible(e);
}
@@ -432,9 +325,9 @@ public class Neo4jTemplate implements Neo4jOperations {
@Override
public <T> T exec(final GraphCallback<T> callback) {
if (transactionManager == null) return doExecute(callback);
if (infrastructure.getTransactionManager() == null) return doExecute(callback);
TransactionTemplate template = new TransactionTemplate(transactionManager);
TransactionTemplate template = new TransactionTemplate(infrastructure.getTransactionManager());
return template.execute(new TransactionCallback<T>() {
public T doInTransaction(TransactionStatus status) {
return doExecute(callback);
@@ -445,7 +338,7 @@ public class Neo4jTemplate implements Neo4jOperations {
@Override
public <T> T getReferenceNode(Class<T> target) {
try {
return convert(graphDatabase.getReferenceNode(), target);
return convert(infrastructure.getGraphDatabase().getReferenceNode(), target);
} catch (RuntimeException e) {
throw translateExceptionIfPossible(e);
}
@@ -455,7 +348,7 @@ public class Neo4jTemplate implements Neo4jOperations {
public Node getNode(long id) {
if (id < 0) throw new InvalidDataAccessApiUsageException("id is negative");
try {
return graphDatabase.getNodeById(id);
return infrastructure.getGraphDatabase().getNodeById(id);
} catch (RuntimeException e) {
throw translateExceptionIfPossible(e);
}
@@ -465,7 +358,7 @@ public class Neo4jTemplate implements Neo4jOperations {
public Relationship getRelationship(long id) {
if (id < 0) throw new InvalidDataAccessApiUsageException("id is negative");
try {
return graphDatabase.getRelationshipById(id);
return infrastructure.getGraphDatabase().getRelationshipById(id);
} catch (RuntimeException e) {
throw translateExceptionIfPossible(e);
}
@@ -478,10 +371,10 @@ public class Neo4jTemplate implements Neo4jOperations {
@Override
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
if (element instanceof Relationship) {
Index<Relationship> relationshipIndex = graphDatabase.createIndex(Relationship.class, indexName, false);
Index<Relationship> relationshipIndex = infrastructure.getGraphDatabase().createIndex(Relationship.class, indexName, false);
relationshipIndex.add((Relationship) element, field, value);
} else if (element instanceof Node) {
graphDatabase.createIndex(Node.class, indexName, false).add((Node) element, field, value);
infrastructure.getGraphDatabase().createIndex(Node.class, indexName, false).add((Node) element, field, value);
} else {
throw new IllegalArgumentException("Provided element is neither node nor relationship " + element);
}
@@ -493,18 +386,18 @@ public class Neo4jTemplate implements Neo4jOperations {
@Override
@SuppressWarnings("unchecked")
public <T> Result<T> convert(Iterable<T> iterable) {
return new QueryResultBuilder<T>(iterable, (ResultConverter<T, ?>) resultConverter);
return new QueryResultBuilder<T>(iterable, (ResultConverter<T, ?>) infrastructure.getResultConverter());
}
@Override
@SuppressWarnings("unchecked")
public <T> T convert(Object value, Class<T> type) {
return (T) resultConverter.convert(value, type);
return (T) infrastructure.getResultConverter().convert(value, type);
}
@Override
public QueryEngine queryEngineFor(QueryType type) {
return graphDatabase.queryEngineFor(type, resultConverter);
return infrastructure.getGraphDatabase().queryEngineFor(type, infrastructure.getResultConverter());
}
@Override
@@ -527,7 +420,6 @@ public class Neo4jTemplate implements Neo4jOperations {
}
// TODO result handling !!
@SuppressWarnings("unchecked")
public <T> Iterable<T> findAllByTraversal(Object entity, Class<?> targetType, TraversalDescription traversalDescription) {
return traverse(entity, traversalDescription).to((Class<T>) targetType);
@@ -576,82 +468,27 @@ public class Neo4jTemplate implements Neo4jOperations {
}
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void setRelationshipEntityInstantiator(EntityInstantiator<Relationship> relationshipEntityInstantiator) {
this.relationshipEntityInstantiator = relationshipEntityInstantiator;
}
public void setNodeEntityInstantiator(EntityInstantiator<Node> nodeEntityInstantiator) {
this.nodeEntityInstantiator = nodeEntityInstantiator;
}
public void setEntityStateHandler(EntityStateHandler entityStateHandler) {
this.entityStateHandler = entityStateHandler;
}
public void setNodeEntityStateFactory(EntityStateFactory<Node> nodeEntityStateFactory) {
this.nodeEntityStateFactory = nodeEntityStateFactory;
}
public void setRelationshipEntityStateFactory(EntityStateFactory<Relationship> relationshipEntityStateFactory) {
this.relationshipEntityStateFactory = relationshipEntityStateFactory;
}
public EntityStateHandler getEntityStateHandler() {
return entityStateHandler;
}
public TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy() {
return nodeTypeRepresentationStrategy;
}
public void setNodeTypeRepresentationStrategy(TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy) {
this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy;
}
public TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy() {
return relationshipTypeRepresentationStrategy;
}
public void setRelationshipTypeRepresentationStrategy(TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy) {
this.relationshipTypeRepresentationStrategy = relationshipTypeRepresentationStrategy;
return infrastructure.getEntityStateHandler();
}
public ConversionService getConversionService() {
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
return infrastructure.getConversionService();
}
public Validator getValidator() {
return validator;
return infrastructure.getValidator();
}
public void setValidator(Validator validatorFactory) {
this.validator = validatorFactory;
}
public void setMappingContext(Neo4jMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
public GraphDatabaseService getGraphDatabaseService() {
return graphDatabaseService;
return infrastructure.getGraphDatabaseService();
}
public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) {
this.graphDatabaseService = graphDatabaseService;
public void setInfrastructure(MappingInfrastructure infrastructure) {
this.infrastructure = infrastructure;
}
public void setGraphDatabase(GraphDatabase graphDatabase) {
this.graphDatabase = graphDatabase;
public MappingInfrastructure getInfrastructure() {
return infrastructure;
}
}

View File

@@ -0,0 +1,33 @@
/**
* 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.springframework.dao.InvalidDataAccessApiUsageException;
/**
* @author mh
* @since 17.10.11
*/
public class ParameterCheck {
public static void notNull(Object... pairs) {
assert pairs.length % 2 == 0 : "wrong number of pairs to check";
for (int i = 0; i < pairs.length; i += 2) {
if (pairs[i] == null) {
throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + pairs[i + 1] + " is required; it must not be null");
}
}
}
}

View File

@@ -19,7 +19,7 @@ package org.springframework.data.neo4j.support.conversion;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.neo4j.conversion.DefaultConverter;
import org.springframework.data.neo4j.core.EntityPath;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.mapping.EntityPersister;
import org.springframework.data.neo4j.support.path.ConvertingEntityPath;
/**
@@ -27,25 +27,25 @@ import org.springframework.data.neo4j.support.path.ConvertingEntityPath;
* @since 28.06.11
*/
public class EntityResultConverter<T,R> extends DefaultConverter<T,R> {
private final Neo4jTemplate template;
private final ConversionService conversionService;
private final EntityPersister entityPersister;
public EntityResultConverter(Neo4jTemplate template) {
this.template = template;
conversionService = this.template.getConversionService();
public EntityResultConverter(ConversionService conversionService, EntityPersister entityPersister) {
this.conversionService = conversionService;
this.entityPersister = entityPersister;
}
@SuppressWarnings("unchecked")
@Override
protected Object doConvert(Object value, Class<?> sourceType, Class targetType) {
if (template.isNodeEntity(targetType)) {
return template.projectTo(toNode(value, sourceType), targetType);
}
if (template.isRelationshipEntity(targetType)) {
return template.projectTo(toRelationship(value, sourceType), targetType);
}
if (EntityPath.class.isAssignableFrom(targetType)) {
return new ConvertingEntityPath(template,toPath(value,sourceType));
return new ConvertingEntityPath(entityPersister,toPath(value,sourceType));
}
if (entityPersister.isNodeEntity(targetType)) {
return entityPersister.projectTo(toNode(value, sourceType), targetType);
}
if (entityPersister.isRelationshipEntity(targetType)) {
return entityPersister.projectTo(toRelationship(value, sourceType), targetType);
}
final Object result = super.doConvert(value, sourceType, targetType);

View File

@@ -22,10 +22,7 @@ import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.helpers.collection.IterableWrapper;
import org.springframework.data.neo4j.core.EntityPath;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.mapping.EntityPersister;
import java.util.Iterator;
@@ -43,8 +40,8 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
private <T> T projectEntityToFirstParameterOrCreateFromStoredType(Node node, Class<T>... types) {
if (node==null) return null;
if (types==null || types.length==0) return template.createEntityFromStoredType(node);
return template.projectTo(node, types[0]);
if (types==null || types.length==0) return persister.createEntityFromStoredType(node);
return persister.projectTo(node, types[0]);
}
@Override
@@ -55,7 +52,7 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
public <T> T lastRelationshipEntity(Class<T>... types) {
Relationship relationship = lastRelationship();
if (relationship==null) return null;
return template.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, types));
return persister.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, types));
}
private static <T> T getFirstOrDefault(final T defaultValue, T... values) {
@@ -68,7 +65,7 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,Node>(nodes()) {
@Override
protected T underlyingObjectToObject(Node node) {
return template.createEntityFromStoredType(node);
return persister.createEntityFromStoredType(node);
}
};
}
@@ -78,7 +75,7 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,Relationship>(relationships()) {
@Override
protected T underlyingObjectToObject(Relationship relationship) {
return template.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
return persister.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
}
};
}
@@ -88,18 +85,18 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,PropertyContainer>(delegate) {
@Override
protected T underlyingObjectToObject(PropertyContainer element) {
return template.projectTo(element, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
return persister.projectTo(element, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
}
};
}
public ConvertingEntityPath(Neo4jTemplate template, Path delegate) {
this.template = template;
public ConvertingEntityPath(EntityPersister persister, Path delegate) {
this.persister = persister;
this.delegate = delegate;
}
private final Neo4jTemplate template;
private final EntityPersister persister;
private final Path delegate;
@Override

View File

@@ -20,19 +20,22 @@ import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;
import org.springframework.data.neo4j.core.EntityPath;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.mapping.EntityPersister;
/**
* @author mh
* @since 26.02.11
*/
public abstract class EntityEvaluator<S, E> implements Evaluator {
private Neo4jTemplate template;
private EntityPersister persister;
protected EntityEvaluator(EntityPersister persister) {
this.persister = persister;
}
@Override
public Evaluation evaluate(Path path) {
return evaluate(new ConvertingEntityPath<S,E>(template, path));
return evaluate(new ConvertingEntityPath<S,E>(persister, path));
}
public abstract Evaluation evaluate(EntityPath<S,E> path);

View File

@@ -16,9 +16,7 @@
package org.springframework.data.neo4j.support.query;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.conversion.Result;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.util.ClassUtils;
import java.util.Map;
@@ -31,11 +29,12 @@ import java.util.Map;
public class CypherQueryExecutor implements QueryOperations<Map<String,Object>> {
private final QueryEngine<Map<String,Object>> queryEngine;
public CypherQueryExecutor(Neo4jTemplate ctx) {
@SuppressWarnings("unchecked")
public CypherQueryExecutor(final QueryEngine queryEngine) {
if (ClassUtils.isPresent("org.neo4j.cypher.javacompat.ExecutionEngine",getClass().getClassLoader())) {
queryEngine = ctx.queryEngineFor(QueryType.Cypher);
this.queryEngine = queryEngine;
} else {
queryEngine = new QueryEngine<Map<String, Object>>() {
this.queryEngine = new QueryEngine<Map<String, Object>>() {
@Override
public Result<Map<String, Object>> query(String statement, Map<String, Object> params) {
throw new IllegalStateException("Cypher is not available, please add it to your dependencies to execute: "+statement);

View File

@@ -27,6 +27,14 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ConfigurationConfirmationTest {
@Test(expected = BeanCreationException.class)
public void testInvalidTransactionManagerFails() {
ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext("classpath:org/springframework/data/neo4j/config/ConfigurationCofirmationTest-context.xml");
ClassPathXmlApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext("classpath:org/springframework/data/neo4j/config/ConfigurationConfirmationTest-context.xml");
ctx.start();
} finally {
if (ctx != null) {
ctx.close();
}
}
}
}

View File

@@ -61,6 +61,7 @@ public class DataGraphNamespaceHandlerTest {
private Config assertInjected(String testCase) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:org/springframework/data/neo4j/config/DataGraphNamespaceHandlerTest" + testCase + "-context.xml");
try {
Config config = ctx.getBean("config", Config.class);
Neo4jTemplate template = config.neo4jTemplate;
Assert.assertNotNull("template", template);
@@ -70,6 +71,9 @@ public class DataGraphNamespaceHandlerTest {
Assert.assertNotNull("transactionManager",config.transactionManager);
config.graphDatabaseService.shutdown();
return config;
} finally {
ctx.close();
}
}
}

View File

@@ -75,7 +75,7 @@ public class Neo4jEntityConverterTest extends Neo4jPersistentTestBase {
public void testFindNewlyWrittenNodeInIndex() {
storeInGraph(michael);
final Node createdNode = michaelNode();
final Index<Node> index = gdc.getIndex(Person.class, Person.NAME_INDEX);
final Index<Node> index = template.getIndex(Person.class, Person.NAME_INDEX);
final Node found = index.get("name", "Michael").getSingle();
assertEquals("node found in index", createdNode, found);
}

View File

@@ -15,12 +15,9 @@
*/
package org.springframework.data.neo4j.mapping;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.neo4j.graphdb.Node;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.model.Friendship;
import org.springframework.data.neo4j.model.Person;
import org.springframework.data.neo4j.support.ManagedEntity;
@@ -35,7 +32,7 @@ public class Neo4jEntityPersisterTest extends Neo4jPersistentTestBase {
@Test
public void testCreateEntityFromStoredType() throws Exception {
final Node personNode = gdc.createNode();
final Node personNode = template.createNode();
personNode.setProperty("name","Michael");
final Person person = entityPersister.createEntityFromState(personNode, Person.class);
assertEquals("Michael",person.getName());

View File

@@ -30,10 +30,7 @@ import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFac
import org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.model.Group;
import org.springframework.data.neo4j.model.Person;
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
import org.springframework.data.neo4j.support.EntityStateHandler;
import org.springframework.data.neo4j.support.EntityTools;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.*;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
@@ -54,7 +51,7 @@ import static java.util.Arrays.asList;
*/
public class Neo4jPersistentTestBase {
private Transaction tx;
protected Neo4jTemplate gdc;
protected Neo4jTemplate template;
protected NodeEntityStateFactory nodeEntityStateFactory;
protected RelationshipEntityStateFactory relationshipEntityStateFactory;
protected EntityStateHandler entityStateHandler;
@@ -85,32 +82,34 @@ public class Neo4jPersistentTestBase {
@Before
public void setUp() throws Exception {
// todo cleanup !!
mappingContext = new Neo4jMappingContext();
gdc = createContext(mappingContext);
tx = gdc.beginTx();
MappingInfrastructure infrastructure = createInfrastructure(mappingContext);
template = new Neo4jTemplate(infrastructure);
nodeEntityStateFactory = createNodeEntityStateFactory(mappingContext);
relationshipEntityStateFactory = createRelationshipEntityStateFactory(mappingContext);
gdc.setNodeEntityStateFactory(nodeEntityStateFactory);
gdc.setRelationshipEntityStateFactory(relationshipEntityStateFactory);
infrastructure.setNodeEntityStateFactory(nodeEntityStateFactory);
infrastructure.setRelationshipEntityStateFactory(relationshipEntityStateFactory);
template.postConstruct();
gdc.postConstruct();
entityStateHandler = gdc.getEntityStateHandler();
entityStateHandler = infrastructure.getEntityStateHandler();
nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler);
relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler);
nodeTypeMapper = new DefaultTypeMapper<Node>(new TRSTypeAliasAccessor<Node>(gdc.getNodeTypeRepresentationStrategy()),asList(new ClassValueTypeInformationMapper()));
nodeTypeMapper = new DefaultTypeMapper<Node>(new TRSTypeAliasAccessor<Node>(infrastructure.getNodeTypeRepresentationStrategy()),asList(new ClassValueTypeInformationMapper()));
nodeStateTransmitter = new SourceStateTransmitter<Node>(nodeEntityStateFactory);
relationshipStateTransmitter = new SourceStateTransmitter<Relationship>(relationshipEntityStateFactory);
conversionService = gdc.getConversionService();
conversionService = template.getConversionService();
fetchHandler = new Neo4jEntityFetchHandler(entityStateHandler, conversionService, nodeStateTransmitter, relationshipStateTransmitter);
final EntityTools<Node> nodeEntityTools = new EntityTools<Node>(gdc.getNodeTypeRepresentationStrategy(), nodeEntityStateFactory, nodeEntityInstantiator);
final EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(gdc.getRelationshipTypeRepresentationStrategy(), relationshipEntityStateFactory, relationshipEntityInstantiator);
final EntityTools<Node> nodeEntityTools = new EntityTools<Node>(infrastructure.getNodeTypeRepresentationStrategy(), nodeEntityStateFactory, nodeEntityInstantiator);
final EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(infrastructure.getRelationshipTypeRepresentationStrategy(), relationshipEntityStateFactory, relationshipEntityInstantiator);
entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
tx = template.beginTx();
group = new Group();
michael = new Person("Michael", 37);
emil = new Person("Emil", 30);
@@ -120,33 +119,32 @@ public class Neo4jPersistentTestBase {
private NodeEntityStateFactory createNodeEntityStateFactory(Neo4jMappingContext mappingContext) {
final NodeEntityStateFactory nodeEntityStateFactory = new NodeEntityStateFactory();
nodeEntityStateFactory.setMappingContext(mappingContext);
nodeEntityStateFactory.setTemplate(gdc);
nodeEntityStateFactory.setNodeDelegatingFieldAccessorFactory(new NodeDelegatingFieldAccessorFactory(gdc));
nodeEntityStateFactory.setTemplate(template);
nodeEntityStateFactory.setNodeDelegatingFieldAccessorFactory(new NodeDelegatingFieldAccessorFactory(template));
return nodeEntityStateFactory;
}
private RelationshipEntityStateFactory createRelationshipEntityStateFactory(Neo4jMappingContext mappingContext) {
final RelationshipEntityStateFactory relationshipEntityStateFactory = new RelationshipEntityStateFactory();
relationshipEntityStateFactory.setMappingContext(mappingContext);
relationshipEntityStateFactory.setTemplate(gdc);
relationshipEntityStateFactory.setRelationshipDelegatingFieldAccessorFactory(new RelationshipDelegatingFieldAccessorFactory(gdc));
relationshipEntityStateFactory.setTemplate(template);
relationshipEntityStateFactory.setRelationshipDelegatingFieldAccessorFactory(new RelationshipDelegatingFieldAccessorFactory(template));
return relationshipEntityStateFactory;
}
private Neo4jTemplate createContext(Neo4jMappingContext mappingContext) throws Exception {
Neo4jTemplate gdc = new Neo4jTemplate();
private MappingInfrastructure createInfrastructure(Neo4jMappingContext mappingContext) throws Exception {
MappingInfrastructure infrastructure=new MappingInfrastructure();
final ImpermanentGraphDatabase gdb = new ImpermanentGraphDatabase();
gdc.setGraphDatabaseService(gdb);
infrastructure.setGraphDatabaseService(gdb);
final DelegatingGraphDatabase graphDatabase = new DelegatingGraphDatabase(gdb);
gdc.setGraphDatabase(graphDatabase);
gdc.setMappingContext(mappingContext);
infrastructure.setGraphDatabase(graphDatabase);
infrastructure.setMappingContext(mappingContext);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
gdc.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy(new NodeEntityInstantiator(entityStateHandler)));
gdc.setRelationshipTypeRepresentationStrategy(new NoopRelationshipTypeRepresentationStrategy(new RelationshipEntityInstantiator(entityStateHandler)));
gdc.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
gdc.setEntityStateHandler(entityStateHandler);
return gdc;
infrastructure.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy(new NodeEntityInstantiator(entityStateHandler)));
infrastructure.setRelationshipTypeRepresentationStrategy(new NoopRelationshipTypeRepresentationStrategy(new RelationshipEntityInstantiator(entityStateHandler)));
infrastructure.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
infrastructure.setEntityStateHandler(entityStateHandler);
return infrastructure;
}
protected List<Node> groupMemberNodes() {
@@ -161,21 +159,21 @@ public class Neo4jPersistentTestBase {
public void tearDown() throws Exception {
tx.failure();
tx.finish();
gdc.getGraphDatabaseService().shutdown();
template.getGraphDatabaseService().shutdown();
}
protected Node michaelNode() {
return gdc.getNode(michael.getId());
return template.getNode(michael.getId());
}
protected Node createNewNode() {
return gdc.createNode();
return template.createNode();
}
protected Group storeInGraph(Group g) {
final Long id = g.getId();
if (id != null) {
write(g, gdc.getNode(id));
write(g, template.getNode(id));
} else {
write(g, null);
}
@@ -185,7 +183,7 @@ public class Neo4jPersistentTestBase {
protected Person storeInGraph(Person p) {
final Long id = p.getId();
if (id != null) {
write(p, gdc.getNode(id));
write(p, template.getNode(id));
} else {
write(p,null);
}
@@ -203,7 +201,7 @@ public class Neo4jPersistentTestBase {
}
protected Node groupNode() {
return gdc.getNode(group.getId());
return template.getNode(group.getId());
}
protected <T> Set<T> set(T... objs) {
@@ -215,11 +213,11 @@ public class Neo4jPersistentTestBase {
}
protected Node andresNode() {
return gdc.getNode(andres.getId());
return template.getNode(andres.getId());
}
protected Node emilNode() {
return gdc.getNode(emil.getId());
return template.getNode(emil.getId());
}
public Person readPerson(Node node) {

View File

@@ -56,6 +56,7 @@ public class GraphDatabaseContextTemplateTest {
private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has");
@Autowired
Neo4jTemplate neo4jTemplate;
@Autowired
protected GraphDatabase graphDatabase;
protected Node referenceNode;
protected Relationship relationship1;
@@ -72,7 +73,7 @@ public class GraphDatabaseContextTemplateTest {
@Before
public void setUp() throws Exception {
Neo4jHelper.cleanDb(neo4jTemplate);
graphDatabase = neo4jTemplate.getGraphDatabase();
// graphDatabase = neo4jTemplate.getGraphDatabase();
referenceNode = graphDatabase.getReferenceNode();
createData();
}