DATAGRAPH-206 resolved cyclic dependency of Neo4j-Template, can now be constructed just with a graph-database-service and is ready to use

This commit is contained in:
Michael Hunger
2012-05-01 03:20:43 +02:00
60 changed files with 1002 additions and 620 deletions

View File

@@ -120,14 +120,14 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
log.error("entityStateFactory not set, not creating accessors for " + entity.getClass());
} else {
if (entity.entityState != null) return;
entity.entityState = entityStateFactory.getEntityState(entity, true);
entity.entityState = entityStateFactory.getEntityState(entity, true, template);
}
}
/**
* State accessors that encapsulate the underlying state and the behaviour related to it (field access, creation)
*/
private transient EntityState<Node> NodeBacked.entityState;
private transient @Transient EntityState<Node> NodeBacked.entityState;
public <T extends NodeBacked> T NodeBacked.persist() {
return (T)this.entityState.persist();
@@ -135,7 +135,7 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
public void NodeBacked.setPersistentState(Node n) {
if (this.entityState == null) {
this.entityState = Neo4jNodeBacking.aspectOf().entityStateFactory.getEntityState(this, false);
this.entityState = Neo4jNodeBacking.aspectOf().entityStateFactory.getEntityState(this, false, getTemplate());
}
this.entityState.setPersistentState(n);
}

View File

@@ -29,7 +29,7 @@ import org.springframework.data.neo4j.core.EntityState;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory;
import org.springframework.data.neo4j.template.Neo4jOperations;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import static org.springframework.data.neo4j.support.DoReturn.unwrap;
@@ -66,7 +66,7 @@ public aspect Neo4jRelationshipBacking {
log.error("entityStateFactory not set, not creating accessors for " + entity.getClass());
} else {
if (entity.entityState != null) return;
entity.entityState = entityStateFactory.getEntityState(entity, true);
entity.entityState = entityStateFactory.getEntityState(entity, true, template);
}
}
@@ -98,7 +98,7 @@ public aspect Neo4jRelationshipBacking {
/**
* field for {@link org.springframework.data.neo4j.core.EntityState} that takes care of all entity operations
*/
private EntityState<Relationship> RelationshipBacked.entityState;
private transient @Transient EntityState<Relationship> RelationshipBacked.entityState;
public Neo4jTemplate RelationshipBacked.getTemplate() {
@@ -107,7 +107,7 @@ public aspect Neo4jRelationshipBacking {
public void RelationshipBacked.setPersistentState(Relationship r) {
if (this.entityState == null) {
this.entityState = Neo4jRelationshipBacking.aspectOf().entityStateFactory.getEntityState(this, true);
this.entityState = Neo4jRelationshipBacking.aspectOf().entityStateFactory.getEntityState(this, true, getTemplate());
}
this.entityState.setPersistentState(r);
}

View File

@@ -43,7 +43,7 @@ public class EntityPathTest extends EntityTestBase {
Person michael = persist(new Person("Michael", 36));
Node node = getNodeState(michael);
NodePath path = new NodePath(node);
EntityPath<Person, Person> entityPath = new ConvertingEntityPath<Person, Person>(neo4jTemplate, path);
EntityPath<Person, Person> entityPath = new ConvertingEntityPath<Person, Person>(path, neo4jTemplate);
Assert.assertEquals("start entity",michael, entityPath.startEntity());
Assert.assertEquals("start node",node, path.startNode());

View File

@@ -71,7 +71,7 @@ public class QueryEngineTest extends EntityTestBase {
public void setUp() throws Exception {
GraphDatabase graphDatabase = createGraphDatabase();
graphDatabase.setConversionService(conversionService);
entityResultConverter = new EntityResultConverter(conversionService, neo4jTemplate);
entityResultConverter = new EntityResultConverter(conversionService);
testTeam.createSDGTeam();
queryEngine = graphDatabase.queryEngineFor(QueryType.Cypher);
michael = testTeam.michael;
@@ -104,7 +104,7 @@ public class QueryEngineTest extends EntityTestBase {
@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(conversionService, template)));
final Collection<Person> result = IteratorUtil.asCollection(queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter(conversionService)));
assertEquals(asList(testTeam.emil),result);
}
@@ -116,7 +116,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>(conversionService, template)).single();
final Person result = queryEngine.query(queryString, michaelsName()).to(Person.class, new EntityResultConverter<Map<String,Object>,Person>(conversionService)).single();
assertEquals(testTeam.emil,result);
}

View File

@@ -32,7 +32,7 @@
<bean id="conversionService" class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructure">
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean">
<property name="graphDatabaseService" ref="graphDatabaseService"/>
<property name="conversionService" ref="conversionService"/>
<property name="mappingContext" ref="mappingContext"/>
@@ -50,8 +50,8 @@
</property>
</bean>
<bean id="template" class="org.springframework.data.neo4j.support.Neo4jTemplate" init-method="postConstruct">
<property name="infrastructure" ref="mappingInfrastructure"/>
<bean id="template" class="org.springframework.data.neo4j.support.Neo4jTemplate">
<constructor-arg name="infrastructure" ref="mappingInfrastructure"/>
</bean>
@@ -78,25 +78,19 @@
<bean id="relationshipTypeRepresentationStrategy" factory-bean="typeRepresentationStrategyFactory" factory-method="getRelationshipTypeRepresentationStrategy"/>
<bean id="nodeEntityStateFactory" class="org.springframework.data.neo4j.support.node.NodeEntityStateFactory">
<property name="nodeDelegatingFieldAccessorFactory">
<bean class="org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory">
<constructor-arg ref="template"/>
</bean>
</property>
<property name="template" ref="template"/>
<property name="mappingContext" ref="mappingContext"/>
<constructor-arg ref="mappingContext"/>
<constructor-arg>
<bean class="org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory$Factory"/>
</constructor-arg>
</bean>
<bean id="mappingContext" class="org.springframework.data.neo4j.support.mapping.Neo4jMappingContext"/>
<bean id="relationshipEntityStateFactory" class="org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory">
<property name="relationshipDelegatingFieldAccessorFactory">
<bean class="org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory">
<constructor-arg ref="template"/>
</bean>
</property>
<property name="template" ref="template"/>
<property name="mappingContext" ref="mappingContext"/>
<constructor-arg ref="mappingContext"/>
<constructor-arg>
<bean class="org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory$Factory"/>
</constructor-arg>
</bean>
<!--bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">

View File

@@ -21,8 +21,10 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.aspects.config.Neo4jAspectConfiguration;
import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityInstantiator;
import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityStateFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.mapping.EntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
@@ -77,10 +79,14 @@ public class CrossStoreNeo4jConfiguration extends Neo4jAspectConfiguration {
}
}
@Override
public FieldAccessorFactoryFactory nodeDelegatingFieldAccessorFactory() throws Exception {
return new CrossStoreNodeDelegatingFieldAccessorFactory.Factory();
}
@Bean
public NodeEntityStateFactory nodeEntityStateFactory() throws Exception {
final CrossStoreNodeEntityStateFactory nodeEntityStateFactory = new CrossStoreNodeEntityStateFactory();
nodeEntityStateFactory.setEntityManagerFactory(entityManagerFactory);
return nodeEntityStateFactory;
return new CrossStoreNodeEntityStateFactory(neo4jMappingContext(),nodeDelegatingFieldAccessorFactory(),entityManagerFactory);
}
}

View File

@@ -0,0 +1,111 @@
/**
* 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.cross_store.support.node;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.cross_store.fieldaccess.JpaIdFieldAccessListenerFactory;
import org.springframework.data.neo4j.fieldaccess.ConvertingNodePropertyFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorListenerFactory;
import org.springframework.data.neo4j.fieldaccess.IndexingPropertyFieldAccessorListenerFactory;
import org.springframework.data.neo4j.fieldaccess.PropertyFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.QueryFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.ReadOnlyRelatedToCollectionFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelatedToCollectionFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelatedToSingleFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelatedToViaSingleFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.TraversalFieldAccessorFactory;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.Arrays;
import java.util.Collection;
/**
* @author mh
* @since 30.04.12
*/
public class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFieldAccessorFactory {
public CrossStoreNodeDelegatingFieldAccessorFactory(Neo4jTemplate template) {
super(template);
}
@Override
protected Collection<FieldAccessorListenerFactory> createListenerFactories() {
return Arrays.asList(
new IndexingPropertyFieldAccessorListenerFactory(
getTemplate(),
newPropertyFieldAccessorFactory(),
newConvertingNodePropertyFieldAccessorFactory()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
},
new JpaIdFieldAccessListenerFactory(template));
}
@Override
protected Collection<? extends FieldAccessorFactory> createAccessorFactories() {
return Arrays.asList(
//new IdFieldAccessorFactory(),
//new TransientFieldAccessorFactory(),
new TraversalFieldAccessorFactory(template),
new QueryFieldAccessorFactory(template),
newPropertyFieldAccessorFactory(),
newConvertingNodePropertyFieldAccessorFactory(),
new RelatedToSingleFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(RelatedTo.class) && super.accept(property);
}
},
new RelatedToCollectionFieldAccessorFactory(getTemplate()),
new ReadOnlyRelatedToCollectionFieldAccessorFactory(getTemplate()),
new RelatedToViaSingleFieldAccessorFactory(getTemplate()),
new RelatedToViaCollectionFieldAccessorFactory(getTemplate())
);
}
private ConvertingNodePropertyFieldAccessorFactory newConvertingNodePropertyFieldAccessorFactory() {
return new ConvertingNodePropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
};
}
private PropertyFieldAccessorFactory newPropertyFieldAccessorFactory() {
return new PropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
};
}
public static class Factory extends FieldAccessorFactoryFactory {
public DelegatingFieldAccessorFactory create(Neo4jTemplate template) {
return new CrossStoreNodeDelegatingFieldAccessorFactory(template);
}
}
}

View File

@@ -47,7 +47,7 @@ public class CrossStoreNodeEntityState<ENTITY extends NodeBacked> extends Defaul
private final Neo4jTemplate template;
private PersistenceUnitUtil persistenceUnitUtil;
public CrossStoreNodeEntityState(final Node underlyingState, final ENTITY entity, final Class<? extends ENTITY> type, final Neo4jTemplate template, PersistenceUnitUtil persistenceUnitUtil, final CrossStoreNodeDelegatingFieldAccessorFactory delegatingFieldAccessorFactory, final Neo4jPersistentEntity persistentEntity) {
public CrossStoreNodeEntityState(final Node underlyingState, final NodeBacked entity, final Class<? extends NodeBacked> type, final Neo4jTemplate template, PersistenceUnitUtil persistenceUnitUtil, final DelegatingFieldAccessorFactory delegatingFieldAccessorFactory, final Neo4jPersistentEntity persistentEntity) {
super(underlyingState, entity, type, delegatingFieldAccessorFactory, persistentEntity);
this.template = template;
this.persistenceUnitUtil = persistenceUnitUtil;
@@ -117,65 +117,4 @@ public class CrossStoreNodeEntityState<ENTITY extends NodeBacked> extends Defaul
return persistenceUnitUtil!=null ? persistenceUnitUtil.getIdentifier(entity) : null;
}
public static class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFieldAccessorFactory {
public CrossStoreNodeDelegatingFieldAccessorFactory(Neo4jTemplate template) {
super(template);
}
@Override
protected Collection<FieldAccessorListenerFactory> createListenerFactories() {
return Arrays.asList(
new IndexingPropertyFieldAccessorListenerFactory(
getTemplate(),
newPropertyFieldAccessorFactory(),
newConvertingNodePropertyFieldAccessorFactory()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
},
new JpaIdFieldAccessListenerFactory(template));
}
@Override
protected Collection<? extends FieldAccessorFactory> createAccessorFactories() {
return Arrays.asList(
//new IdFieldAccessorFactory(),
//new TransientFieldAccessorFactory(),
new TraversalFieldAccessorFactory(template),
new QueryFieldAccessorFactory(template),
newPropertyFieldAccessorFactory(),
newConvertingNodePropertyFieldAccessorFactory(),
new RelatedToSingleFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(RelatedTo.class) && super.accept(property);
}
},
new RelatedToCollectionFieldAccessorFactory(getTemplate()),
new ReadOnlyRelatedToCollectionFieldAccessorFactory(getTemplate()),
new RelatedToViaSingleFieldAccessorFactory(getTemplate()),
new RelatedToViaCollectionFieldAccessorFactory(getTemplate())
);
}
private ConvertingNodePropertyFieldAccessorFactory newConvertingNodePropertyFieldAccessorFactory() {
return new ConvertingNodePropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
};
}
private PropertyFieldAccessorFactory newPropertyFieldAccessorFactory() {
return new PropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
}
};
}
}
}

View File

@@ -19,9 +19,12 @@ import org.neo4j.graphdb.Node;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.aspects.core.NodeBacked;
import org.springframework.data.neo4j.core.EntityState;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.DetachedEntityState;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
import javax.persistence.EntityManagerFactory;
@@ -32,16 +35,21 @@ import javax.persistence.PersistenceUnitUtil;
* @since 30.09.11
*/
public class CrossStoreNodeEntityStateFactory extends NodeEntityStateFactory {
private CrossStoreNodeEntityState.CrossStoreNodeDelegatingFieldAccessorFactory delegatingFieldAccessorFactory;
private EntityManagerFactory entityManagerFactory;
private final EntityManagerFactory entityManagerFactory;
public EntityState<Node> getEntityState(final Object entity, boolean detachable) {
public CrossStoreNodeEntityStateFactory(Neo4jMappingContext neo4jMappingContext, FieldAccessorFactoryFactory factory, EntityManagerFactory entityManagerFactory) {
super(neo4jMappingContext, factory);
this.entityManagerFactory = entityManagerFactory;
}
public EntityState<Node> getEntityState(final Object entity, boolean detachable, Neo4jTemplate template) {
final Class<?> entityType = entity.getClass();
if (isPartial(entityType)) {
final Neo4jPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityType);
final DelegatingFieldAccessorFactory fieldAccessorFactory = nodeDelegatingFieldAccessorFactory.provideFactoryFor(template);
@SuppressWarnings("unchecked") final CrossStoreNodeEntityState<NodeBacked> partialNodeEntityState =
new CrossStoreNodeEntityState<NodeBacked>(null, (NodeBacked)entity, (Class<? extends NodeBacked>) entityType,
template, getPersistenceUnitUtils(), delegatingFieldAccessorFactory,
template, getPersistenceUnitUtils(), fieldAccessorFactory,
persistentEntity);
if (!detachable) return partialNodeEntityState;
return new DetachedEntityState<Node>(partialNodeEntityState, template) {
@@ -51,7 +59,7 @@ public class CrossStoreNodeEntityStateFactory extends NodeEntityStateFactory {
}
};
} else {
return super.getEntityState(entity,detachable);
return super.getEntityState(entity,detachable, template);
}
}
@@ -64,15 +72,4 @@ public class CrossStoreNodeEntityStateFactory extends NodeEntityStateFactory {
if (entityManagerFactory == null|| !entityManagerFactory.isOpen()) return null;
return entityManagerFactory.getPersistenceUnitUtil();
}
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Override
public void setTemplate(Neo4jTemplate template) {
super.setTemplate(template);
this.delegatingFieldAccessorFactory = new CrossStoreNodeEntityState.CrossStoreNodeDelegatingFieldAccessorFactory(template);
}
}

View File

@@ -0,0 +1,30 @@
/**
* 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.partial;
import org.junit.runner.RunWith;
import org.springframework.test.context.CleanContextCacheTestExecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:org/springframework/data/neo4j/partial/Neo4jGraphRecommendationTest-context-config.xml"})
@TestExecutionListeners({CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
public class RecommendationConfigTest extends RecommendationTest {
}

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">
<neo4j:config graphDatabaseService="graphDatabaseService" entityManagerFactory="entityManagerFactory"/>
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase"
destroy-method="shutdown" scope="singleton">
</bean>
<context:property-placeholder location="classpath*:META-INF/spring/database.properties"/>
<context:spring-configured/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.SharedEntityManagerCreator" factory-method="createSharedEntityManager">
<constructor-arg ref="entityManagerFactory"/>
</bean>
</beans>

View File

@@ -14,34 +14,10 @@
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--
This will automatically locate any and all property files you have
within your classpath, provided they fall under the META-INF/spring
directory. The located property files are parsed and their values can
then be used within application context files in the form of
${propertyKey}.
-->
<context:property-placeholder location="classpath*:META-INF/spring/database.properties"/>
<!--
Turn on AspectJ @Configurable support. As a result, any time you
instantiate an object, Spring will attempt to perform dependency
injection on that object. This occurs for instantiation via the "new"
keyword, as well as via reflection. This is possible because AspectJ
is used to "weave" Roo-based applications at compile time. In effect
this feature allows dependency injection of any object at all in your
system, which is a very useful feature (without @Configurable you'd
only be able to dependency inject objects acquired from Spring or
subsequently presented to a specific Spring dependency injection
method). Roo applications use this useful feature in a number of
areas, such as @PersistenceContext injection into entities.
-->
<context:spring-configured/>
<!--
Start datastore config
-->
<bean id="neo4jNodeBacking" class="org.springframework.data.neo4j.aspects.support.node.Neo4jNodeBacking" factory-method="aspectOf">
<property name="template" ref="neo4jTemplate"/>
<property name="nodeEntityStateFactory" ref="nodeEntityStateFactory"/>
@@ -61,7 +37,7 @@
<constructor-arg ref="graphDatabaseService"/>
</bean>
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructure">
<bean id="mappingInfrastructure" class="org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean">
<property name="graphDatabaseService" ref="graphDatabaseService"/>
<property name="conversionService">
<bean class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
@@ -76,7 +52,7 @@
</bean>
<bean id="neo4jTemplate" class="org.springframework.data.neo4j.support.Neo4jTemplate">
<property name="infrastructure" ref="mappingInfrastructure"/>
<constructor-arg name="infrastructure" ref="mappingInfrastructure"/>
</bean>
<bean id="graphEntityInstantiator" class="org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityInstantiator">
<constructor-arg ref="nodeEntityInstantiator"/>
@@ -102,27 +78,21 @@
<bean id="relationshipTypeRepresentationStrategy" factory-bean="typeRepresentationStrategyFactory" factory-method="getRelationshipTypeRepresentationStrategy"/>
<bean id="nodeEntityStateFactory" class="org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityStateFactory">
<property name="nodeDelegatingFieldAccessorFactory">
<bean class="org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory">
<constructor-arg ref="neo4jTemplate"/>
</bean>
</property>
<property name="template" ref="neo4jTemplate"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="mappingContext" ref="mappingContext"/>
<constructor-arg ref="mappingContext"/>
<constructor-arg>
<bean class="org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeDelegatingFieldAccessorFactory$Factory"/>
</constructor-arg>
<constructor-arg name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="mappingContext" class="org.springframework.data.neo4j.support.mapping.Neo4jMappingContext"/>
<bean id="relationshipEntityStateFactory" class="org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory">
<property name="relationshipDelegatingFieldAccessorFactory">
<bean class="org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory">
<constructor-arg ref="neo4jTemplate"/>
</bean>
</property>
<property name="template" ref="neo4jTemplate"/>
<property name="mappingContext" ref="mappingContext"/>
<constructor-arg ref="mappingContext"/>
<constructor-arg>
<bean class="org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory$Factory"/>
</constructor-arg>
</bean>

View File

@@ -218,7 +218,7 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.2</version>
<version>1.8.3</version>
</dependency>
<dependency>

View File

@@ -1,5 +1,6 @@
package org.neo4j.cineasts.movieimport;
import org.codehaus.jackson.map.ObjectMapper;
import java.net.URL;

View File

@@ -237,7 +237,7 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.2</version>
<version>1.8.3</version>
</dependency>
<dependency>

View File

@@ -218,7 +218,7 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.2</version>
<version>1.8.3</version>
</dependency>
<dependency>

View File

@@ -7,13 +7,13 @@
<version>2.1.0.BUILD-SNAPSHOT</version>
<name>myrestaurants-social</name>
<properties>
<spring.version>3.0.7.RELEASE</spring.version>
<spring.version>3.1.0.RELEASE</spring.version>
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<aspectj.version>1.6.12</aspectj.version>
<slf4j.version>1.6.1</slf4j.version>
<neo4j.version>1.7</neo4j.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-security.version>3.0.7.RELEASE</spring-security.version>
<spring-security.version>3.1.0.RELEASE</spring-security.version>
</properties>
<repositories>
<repository>

View File

@@ -7,7 +7,6 @@ import javax.validation.Valid;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;

View File

@@ -20,7 +20,8 @@
<!--
neo4j datastore config
-->
<context:annotation-config/>
<!--context:annotation-config/-->
<context:spring-configured/>
<neo4j:config storeDirectory="target/db-test" entityManagerFactory="entityManagerFactory"/>
@@ -33,4 +34,5 @@
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
</beans>

View File

@@ -1,30 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">
<import resource="DataStore-context.xml"/>
<context:spring-configured/>
<context:annotation-config/>
<context:spring-configured/>
<neo4j:config storeDirectory="target/db-test" entityManagerFactory="entityManagerFactory"/>
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:restaurants-sample-data.sql"/>
</jdbc:embedded-database>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"><!--depends-on="neo4jNodeBacking"-->
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<context:component-scan base-package="com.springone.myrestaurants">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
</beans>

View File

@@ -732,7 +732,7 @@
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
<configuration>
<failOnWarnings>true</failOnWarnings>
<failOnWarnings>false</failOnWarnings>
</configuration>
<executions>
<execution>

View File

@@ -26,19 +26,20 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.TypeMapper;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.core.TypeRepresentationStrategy;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean;
import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.RelationshipDelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.mapping.EntityInstantiator;
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
import org.springframework.data.neo4j.support.MappingInfrastructure;
import org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean;
import org.springframework.data.neo4j.support.Neo4jExceptionTranslator;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.index.IndexProvider;
@@ -91,46 +92,42 @@ public abstract class Neo4jConfiguration {
this.conversionService = conversionService;
}
@Autowired
@Autowired(required = true)
public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) {
this.graphDatabaseService = graphDatabaseService;
}
@Bean
public MappingInfrastructure mappingInfrastructure() throws Exception {
MappingInfrastructure infrastructure = new MappingInfrastructure();
infrastructure.setGraphDatabaseService(getGraphDatabaseService());
infrastructure.setTypeRepresentationStrategyFactory(typeRepresentationStrategyFactory());
infrastructure.setConversionService(neo4jConversionService());
infrastructure.setMappingContext(neo4jMappingContext());
infrastructure.setEntityStateHandler(entityStateHandler());
public MappingInfrastructureFactoryBean mappingInfrastructure() throws Exception {
MappingInfrastructureFactoryBean factoryBean = new MappingInfrastructureFactoryBean();
factoryBean.setGraphDatabaseService(getGraphDatabaseService());
factoryBean.setTypeRepresentationStrategyFactory(typeRepresentationStrategyFactory());
factoryBean.setConversionService(neo4jConversionService());
factoryBean.setMappingContext(neo4jMappingContext());
factoryBean.setEntityStateHandler(entityStateHandler());
infrastructure.setNodeEntityStateFactory(nodeEntityStateFactory());
infrastructure.setNodeTypeRepresentationStrategy(nodeTypeRepresentationStrategy());
infrastructure.setNodeEntityInstantiator(graphEntityInstantiator());
factoryBean.setNodeEntityStateFactory(nodeEntityStateFactory());
factoryBean.setNodeTypeRepresentationStrategy(nodeTypeRepresentationStrategy());
factoryBean.setNodeEntityInstantiator(graphEntityInstantiator());
infrastructure.setRelationshipEntityStateFactory(relationshipEntityStateFactory());
infrastructure.setRelationshipTypeRepresentationStrategy(relationshipTypeRepresentationStrategy());
infrastructure.setRelationshipEntityInstantiator(graphRelationshipInstantiator());
factoryBean.setRelationshipEntityStateFactory(relationshipEntityStateFactory());
factoryBean.setRelationshipTypeRepresentationStrategy(relationshipTypeRepresentationStrategy());
factoryBean.setRelationshipEntityInstantiator(graphRelationshipInstantiator());
infrastructure.setTransactionManager(neo4jTransactionManager());
infrastructure.setGraphDatabase(graphDatabase());
factoryBean.setTransactionManager(neo4jTransactionManager());
factoryBean.setGraphDatabase(graphDatabase());
infrastructure.setIndexProvider(indexProvider());
factoryBean.setIndexProvider(indexProvider());
if (validator!=null) {
infrastructure.setValidator(validator);
factoryBean.setValidator(validator);
}
return infrastructure;
return factoryBean;
}
@Bean(initMethod="postConstruct")
@Bean
public Neo4jTemplate neo4jTemplate() throws Exception {
final Neo4jTemplate neo4jTemplate = new Neo4jTemplate();
neo4jTemplate.setInfrastructure(mappingInfrastructure());
nodeEntityStateFactory().setTemplate(neo4jTemplate);
relationshipEntityStateFactory().setTemplate(neo4jTemplate);
return neo4jTemplate;
return new Neo4jTemplate(mappingInfrastructure().getObject());
}
@Bean
@@ -201,9 +198,6 @@ public abstract class Neo4jConfiguration {
public Neo4jMappingContext neo4jMappingContext() throws Exception {
final Neo4jMappingContext mappingContext = new Neo4jMappingContext();
mappingContext.setEntityAlias(entityAlias());
nodeEntityStateFactory().setMappingContext(mappingContext);
relationshipEntityStateFactory().setMappingContext(mappingContext);
return mappingContext;
}
@@ -214,26 +208,22 @@ public abstract class Neo4jConfiguration {
@Bean
public RelationshipEntityStateFactory relationshipEntityStateFactory() throws Exception {
return new RelationshipEntityStateFactory();
return new RelationshipEntityStateFactory(neo4jMappingContext(),relationshipDelegatingFieldAccessorFactory());
}
@Bean
public NodeEntityStateFactory nodeEntityStateFactory() throws Exception {
return new NodeEntityStateFactory();
return new NodeEntityStateFactory(neo4jMappingContext(), nodeDelegatingFieldAccessorFactory());
}
@Bean
public DelegatingFieldAccessorFactory nodeDelegatingFieldAccessorFactory() throws Exception {
final NodeDelegatingFieldAccessorFactory nodeDelegatingFieldAccessorFactory = new NodeDelegatingFieldAccessorFactory(neo4jTemplate());
nodeEntityStateFactory().setNodeDelegatingFieldAccessorFactory(nodeDelegatingFieldAccessorFactory);
return nodeDelegatingFieldAccessorFactory;
public FieldAccessorFactoryFactory nodeDelegatingFieldAccessorFactory() throws Exception {
return new NodeDelegatingFieldAccessorFactory.Factory();
}
@Bean
public DelegatingFieldAccessorFactory relationshipDelegatingFieldAccessorFactory() throws Exception {
final RelationshipDelegatingFieldAccessorFactory relationshipDelegatingFieldAccessorFactory = new RelationshipDelegatingFieldAccessorFactory(neo4jTemplate());
relationshipEntityStateFactory().setRelationshipDelegatingFieldAccessorFactory(relationshipDelegatingFieldAccessorFactory);
return relationshipDelegatingFieldAccessorFactory;
public FieldAccessorFactoryFactory relationshipDelegatingFieldAccessorFactory() throws Exception {
return new RelationshipDelegatingFieldAccessorFactory.Factory();
}
@Bean(name = {"neo4jTransactionManager","transactionManager"})
@@ -263,6 +253,8 @@ public abstract class Neo4jConfiguration {
}
@Bean
@Autowired
@DependsOn("graphDatabaseService")
public GraphDatabase graphDatabase() {
if (graphDatabaseService instanceof GraphDatabase) return (GraphDatabase) graphDatabaseService;
return new DelegatingGraphDatabase(graphDatabaseService);
@@ -282,4 +274,5 @@ public abstract class Neo4jConfiguration {
public IndexProvider indexProvider() throws Exception {
return new IndexProviderImpl(neo4jMappingContext(), graphDatabase());
}
}

View File

@@ -78,21 +78,21 @@ public class DefaultConverter<T,R> implements ResultConverter<T,R> {
return null;
}
protected Path toPath(Object value, Class<?> sourceType) {
public Path toPath(Object value, Class<?> sourceType) {
if (Node.class.isAssignableFrom(sourceType)) return new NodePath((Node) value);
if (Relationship.class.isAssignableFrom(sourceType)) return new RelationshipPath((Relationship) value);
if (Path.class.isAssignableFrom(sourceType)) return (Path) value;
return null;
}
protected Relationship toRelationship(Object value, Class<?> sourceType) {
public Relationship toRelationship(Object value, Class<?> sourceType) {
if (Relationship.class.isAssignableFrom(sourceType)) return ((Relationship) value);
if (Path.class.isAssignableFrom(sourceType)) return ((Path) value).lastRelationship();
if (Node.class.isAssignableFrom(sourceType)) return ((Node) value).getRelationships().iterator().next();
return null;
}
protected Node toNode(Object value, Class<?> sourceType) {
public Node toNode(Object value, Class<?> sourceType) {
if (Node.class.isAssignableFrom(sourceType)) return (Node)value;
if (Path.class.isAssignableFrom(sourceType)) return ((Path) value).endNode();
if (Relationship.class.isAssignableFrom(sourceType)) return ((Relationship) value).getEndNode();

View File

@@ -0,0 +1,38 @@
/**
* 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.springframework.data.neo4j.support.Neo4jTemplate;
/**
* @author mh
* @since 24.04.12
*/
public abstract class FieldAccessorFactoryFactory {
private DelegatingFieldAccessorFactory accessorFactory;
public abstract DelegatingFieldAccessorFactory create(Neo4jTemplate template);
public DelegatingFieldAccessorFactory provideFactoryFor(Neo4jTemplate template) {
if (accessorFactory != null) return accessorFactory;
synchronized (this) {
if (accessorFactory != null) return accessorFactory;
accessorFactory = create(template);
return accessorFactory;
}
}
}

View File

@@ -60,4 +60,11 @@ public class NodeDelegatingFieldAccessorFactory extends DelegatingFieldAccessorF
new DynamicPropertiesFieldAccessorFactory(template)
);
}
public static class Factory extends FieldAccessorFactoryFactory {
@Override
public DelegatingFieldAccessorFactory create(Neo4jTemplate template) {
return new NodeDelegatingFieldAccessorFactory(template);
}
}
}

View File

@@ -48,4 +48,11 @@ public class RelationshipDelegatingFieldAccessorFactory extends DelegatingFieldA
new DynamicPropertiesFieldAccessorFactory(template)
);
}
public static class Factory extends FieldAccessorFactoryFactory {
@Override
public DelegatingFieldAccessorFactory create(Neo4jTemplate template) {
return new RelationshipDelegatingFieldAccessorFactory(template);
}
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.data.neo4j.mapping;
import org.neo4j.graphdb.PropertyContainer;
import org.springframework.data.neo4j.support.Neo4jTemplate;
/**
* @author mh
@@ -23,11 +24,11 @@ import org.neo4j.graphdb.PropertyContainer;
*/
public interface EntityPersister {
<T> T projectTo(Object entity, Class<T> targetType);
<T> T projectTo(Object entity, Class<T> targetType, MappingPolicy mappingPolicy);
<S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type, MappingPolicy mappingPolicy);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state);
<T> T projectTo(Object entity, Class<T> targetType, final Neo4jTemplate template);
<T> T projectTo(Object entity, Class<T> targetType, MappingPolicy mappingPolicy, final Neo4jTemplate template);
<S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type, MappingPolicy mappingPolicy, final Neo4jTemplate template);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy, final Neo4jTemplate template);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state, final Neo4jTemplate template);
boolean isNodeEntity(Class<?> targetType);
boolean isRelationshipEntity(Class<?> targetType);
MappingPolicy getMappingPolicy(Class<?> targetType);

View File

@@ -18,6 +18,7 @@ package org.springframework.data.neo4j.mapping;
import org.neo4j.graphdb.PropertyContainer;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.mapping.Neo4jPersistentEntityImpl;
/**
@@ -25,9 +26,9 @@ import org.springframework.data.neo4j.support.mapping.Neo4jPersistentEntityImpl;
* @since 27.09.11
*/
public interface Neo4jEntityConverter<T, S extends PropertyContainer> {
<R extends T> R read(Class<R> type, S source, MappingPolicy mappingPolicy);
void write(T source, S sink, MappingPolicy mappingPolicy);
<R extends T> R read(Class<R> type, S source, MappingPolicy mappingPolicy, final Neo4jTemplate template);
void write(T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template);
MappingContext<? extends Neo4jPersistentEntity<?>, Neo4jPersistentProperty> getMappingContext();
ConversionService getConversionService();
<R extends T> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity);
<R extends T> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity, final Neo4jTemplate template);
}

View File

@@ -0,0 +1,71 @@
/**
* 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.conversion.ResultConverter;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.core.TypeRepresentationStrategy;
import org.springframework.data.neo4j.mapping.EntityInstantiator;
import org.springframework.data.neo4j.support.index.IndexProvider;
import org.springframework.data.neo4j.support.mapping.EntityRemover;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.node.EntityStateFactory;
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
import org.springframework.transaction.PlatformTransactionManager;
import javax.validation.Validator;
/**
* @author mh
* @since 24.04.12
*/
public interface Infrastructure {
EntityStateHandler getEntityStateHandler();
ConversionService getConversionService();
Validator getValidator();
GraphDatabaseService getGraphDatabaseService();
GraphDatabase getGraphDatabase();
ResultConverter getResultConverter();
EntityRemover getEntityRemover();
IndexProvider getIndexProvider();
Neo4jEntityPersister getEntityPersister();
PlatformTransactionManager getTransactionManager();
TypeRepresentationStrategies getTypeRepresentationStrategies();
Neo4jMappingContext getMappingContext();
TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy();
TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy();
}

View File

@@ -19,23 +19,17 @@ 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.EntityInstantiator;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.index.IndexProvider;
import org.springframework.data.neo4j.support.index.IndexProviderImpl;
import org.springframework.data.neo4j.support.mapping.EntityRemover;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.EntityTools;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
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.TypeRepresentationStrategies;
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
import org.springframework.transaction.PlatformTransactionManager;
@@ -46,198 +40,111 @@ import javax.validation.Validator;
* @author mh
* @since 17.10.11
*/
public class MappingInfrastructure {
private ConversionService conversionService;
private Validator validator;
private TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy;
public class MappingInfrastructure implements Infrastructure {
private TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy;
private final ConversionService conversionService;
private final Validator validator;
private final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy;
private TypeRepresentationStrategyFactory typeRepresentationStrategyFactory;
private final 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;
private final Neo4jMappingContext mappingContext;
private final CypherQueryExecutor cypherQueryExecutor;
private final EntityStateHandler entityStateHandler;
private final Neo4jEntityPersister entityPersister;
private final EntityRemover entityRemover;
private final TypeRepresentationStrategies typeRepresentationStrategies;
private final PlatformTransactionManager transactionManager;
private final ResultConverter resultConverter;
private final IndexProvider indexProvider;
private final GraphDatabaseService graphDatabaseService;
private final GraphDatabase graphDatabase;
public MappingInfrastructure(GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
public MappingInfrastructure(GraphDatabase graphDatabase, GraphDatabaseService graphDatabaseService, IndexProvider indexProvider, ResultConverter resultConverter, PlatformTransactionManager transactionManager, TypeRepresentationStrategies typeRepresentationStrategies, EntityRemover entityRemover, Neo4jEntityPersister entityPersister, EntityStateHandler entityStateHandler, CypherQueryExecutor cypherQueryExecutor, Neo4jMappingContext mappingContext, TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy, TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy, Validator validator, ConversionService conversionService) {
this.graphDatabase = graphDatabase;
this.graphDatabaseService = graphDatabaseService;
this.indexProvider = indexProvider;
this.resultConverter = resultConverter;
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.typeRepresentationStrategyFactory==null) {
this.typeRepresentationStrategyFactory = new TypeRepresentationStrategyFactory(graphDatabase);
}
if (this.nodeTypeRepresentationStrategy == null) {
this.nodeTypeRepresentationStrategy = typeRepresentationStrategyFactory.getNodeTypeRepresentationStrategy();
}
if (this.relationshipTypeRepresentationStrategy == null) {
this.relationshipTypeRepresentationStrategy = typeRepresentationStrategyFactory.getRelationshipTypeRepresentationStrategy();
}
this.typeRepresentationStrategies = new TypeRepresentationStrategies(mappingContext, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
EntityTools<Node> nodeEntityTools = new EntityTools<Node>(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator,mappingContext);
EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator, mappingContext);
this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, 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));
if (this.indexProvider == null) {
this.indexProvider = new IndexProviderImpl(this.mappingContext, graphDatabase);
}
}
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.typeRepresentationStrategies = typeRepresentationStrategies;
this.entityRemover = entityRemover;
this.entityPersister = entityPersister;
this.entityStateHandler = entityStateHandler;
this.cypherQueryExecutor = cypherQueryExecutor;
this.mappingContext = mappingContext;
this.relationshipTypeRepresentationStrategy = relationshipTypeRepresentationStrategy;
this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy;
this.validator = validator;
this.conversionService = conversionService;
}
public void setNodeEntityStateFactory(EntityStateFactory<Node> nodeEntityStateFactory) {
this.nodeEntityStateFactory = nodeEntityStateFactory;
}
public void setRelationshipEntityStateFactory(EntityStateFactory<Relationship> relationshipEntityStateFactory) {
this.relationshipEntityStateFactory = relationshipEntityStateFactory;
}
@Override
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;
}
@Override
public ConversionService getConversionService() {
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
@Override
public Validator getValidator() {
return validator;
}
public void setValidator(Validator validatorFactory) {
this.validator = validatorFactory;
}
public void setMappingContext(Neo4jMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
@Override
public GraphDatabaseService getGraphDatabaseService() {
return graphDatabaseService;
}
public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) {
this.graphDatabaseService = graphDatabaseService;
}
public void setGraphDatabase(GraphDatabase graphDatabase) {
this.graphDatabase = graphDatabase;
}
@Override
public GraphDatabase getGraphDatabase() {
return graphDatabase;
}
@Override
public ResultConverter getResultConverter() {
return resultConverter;
}
@Override
public EntityRemover getEntityRemover() {
return entityRemover;
}
@Override
public IndexProvider getIndexProvider() {
return indexProvider;
}
@Override
public Neo4jEntityPersister getEntityPersister() {
return entityPersister;
}
@Override
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
@Override
public TypeRepresentationStrategies getTypeRepresentationStrategies() {
return typeRepresentationStrategies;
}
public CypherQueryExecutor getCypherQueryExecutor() {
return cypherQueryExecutor;
}
@Override
public Neo4jMappingContext getMappingContext() {
return mappingContext;
}
public void setTypeRepresentationStrategyFactory(TypeRepresentationStrategyFactory typeRepresentationStrategyFactory) {
this.typeRepresentationStrategyFactory = typeRepresentationStrategyFactory;
@Override
public TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy() {
return nodeTypeRepresentationStrategy;
}
public void setIndexProvider(IndexProvider indexProvider) {
this.indexProvider = indexProvider;
@Override
public TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy() {
return relationshipTypeRepresentationStrategy;
}
}

View File

@@ -0,0 +1,271 @@
/**
* 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.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
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.EntityInstantiator;
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
import org.springframework.data.neo4j.support.index.IndexProvider;
import org.springframework.data.neo4j.support.index.IndexProviderImpl;
import org.springframework.data.neo4j.support.mapping.EntityRemover;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.EntityTools;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
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.TypeRepresentationStrategies;
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
import org.springframework.transaction.PlatformTransactionManager;
import javax.validation.Validator;
/**
* @author mh
* @since 17.10.11
*/
public class MappingInfrastructureFactoryBean implements FactoryBean<Infrastructure>, InitializingBean {
private ConversionService conversionService;
private Validator validator;
private TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy;
private TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy;
private TypeRepresentationStrategyFactory typeRepresentationStrategyFactory;
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;
private MappingInfrastructure mappingInfrastructure;
public MappingInfrastructureFactoryBean(GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
this.graphDatabase = graphDatabase;
this.transactionManager = transactionManager;
}
public MappingInfrastructureFactoryBean(GraphDatabaseService graphDatabaseService, PlatformTransactionManager transactionManager) {
this.graphDatabaseService = graphDatabaseService;
this.transactionManager = transactionManager;
}
public MappingInfrastructureFactoryBean() {
}
@Override
public void afterPropertiesSet() {
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.typeRepresentationStrategyFactory == null) {
this.typeRepresentationStrategyFactory = new TypeRepresentationStrategyFactory(graphDatabase);
}
if (this.nodeTypeRepresentationStrategy == null) {
this.nodeTypeRepresentationStrategy = typeRepresentationStrategyFactory.getNodeTypeRepresentationStrategy();
}
if (this.relationshipTypeRepresentationStrategy == null) {
this.relationshipTypeRepresentationStrategy = typeRepresentationStrategyFactory.getRelationshipTypeRepresentationStrategy();
}
this.typeRepresentationStrategies = new TypeRepresentationStrategies(mappingContext, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
EntityTools<Node> nodeEntityTools = new EntityTools<Node>(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator, mappingContext);
EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator, mappingContext);
this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, graphDatabase);
if (this.resultConverter == null) {
this.resultConverter = new EntityResultConverter<Object, Object>(conversionService);
}
this.graphDatabase.setResultConverter(resultConverter);
this.cypherQueryExecutor = new CypherQueryExecutor(graphDatabase.queryEngineFor(QueryType.Cypher, resultConverter));
if (this.indexProvider == null) {
this.indexProvider = new IndexProviderImpl(this.mappingContext, graphDatabase);
}
this.mappingInfrastructure = new MappingInfrastructure(graphDatabase, graphDatabaseService, indexProvider, resultConverter, transactionManager, typeRepresentationStrategies, entityRemover, entityPersister, entityStateHandler, cypherQueryExecutor, mappingContext, relationshipTypeRepresentationStrategy, nodeTypeRepresentationStrategy, validator, conversionService);
}
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;
}
public Neo4jMappingContext getMappingContext() {
return mappingContext;
}
public void setTypeRepresentationStrategyFactory(TypeRepresentationStrategyFactory typeRepresentationStrategyFactory) {
this.typeRepresentationStrategyFactory = typeRepresentationStrategyFactory;
}
public void setIndexProvider(IndexProvider indexProvider) {
this.indexProvider = indexProvider;
}
@Override
public Infrastructure getObject() {
return mappingInfrastructure;
}
@Override
public Class<?> getObjectType() {
return Infrastructure.class;
}
@Override
public boolean isSingleton() {
return true;
}
public static Infrastructure createDirect(GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
final MappingInfrastructureFactoryBean factoryBean = new MappingInfrastructureFactoryBean(graphDatabase, transactionManager);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
}

View File

@@ -36,7 +36,7 @@ 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.fieldaccess.GraphBackedEntityIterableWrapper;
import org.springframework.data.neo4j.mapping.EntityPersister;
import org.springframework.data.neo4j.mapping.EntityPersister2;
import org.springframework.data.neo4j.mapping.IndexInfo;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
@@ -80,17 +80,10 @@ import static org.springframework.data.neo4j.support.ParameterCheck.notNull;
/*
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 {
public class Neo4jTemplate implements Neo4jOperations , EntityPersister2 {
private static final Logger log = LoggerFactory.getLogger(Neo4jTemplate.class);
private MappingInfrastructure infrastructure = new MappingInfrastructure();
/**
* default constructor for dependency injection, TODO provide dependencies at creation time
*/
public Neo4jTemplate() {
this.infrastructure = new MappingInfrastructure();
}
private final Infrastructure infrastructure;
/**
* @param graphDatabase the neo4j graph database
@@ -98,15 +91,15 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
*/
public Neo4jTemplate(final GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) {
notNull(graphDatabase, "graphDatabase");
this.infrastructure = new MappingInfrastructure(graphDatabase,transactionManager);
this.infrastructure = MappingInfrastructureFactoryBean.createDirect(graphDatabase,transactionManager);
}
public Neo4jTemplate(final GraphDatabase graphDatabase) {
notNull(graphDatabase, "graphDatabase");
this.infrastructure = new MappingInfrastructure(graphDatabase,null);
this.infrastructure = MappingInfrastructureFactoryBean.createDirect(graphDatabase,null);
}
public Neo4jTemplate(MappingInfrastructure infrastructure) {
public Neo4jTemplate(Infrastructure infrastructure) {
this.infrastructure = infrastructure;
}
@@ -148,12 +141,12 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
if (persistentEntity.isNodeEntity()) {
final Node node = getNode(id);
if (node==null) return null;
return infrastructure.getEntityPersister().createEntityFromState(node, entityClass, persistentEntity.getMappingPolicy());
return infrastructure.getEntityPersister().createEntityFromState(node, entityClass, persistentEntity.getMappingPolicy(), this);
}
if (persistentEntity.isRelationshipEntity()) {
final Relationship relationship = getRelationship(id);
if (relationship==null) return null;
return infrastructure.getEntityPersister().createEntityFromState(relationship, entityClass, persistentEntity.getMappingPolicy());
return infrastructure.getEntityPersister().createEntityFromState(relationship, entityClass, persistentEntity.getMappingPolicy(), this);
}
throw new IllegalArgumentException("provided entity type is not annotated with @NodeEntiy nor @RelationshipEntity");
}
@@ -174,34 +167,34 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
@Override
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state) {
notNull(state,"node or relationship");
return infrastructure.getEntityPersister().createEntityFromStoredType(state);
return infrastructure.getEntityPersister().createEntityFromStoredType(state, this);
}
@Override
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy) {
notNull(state,"node or relationship");
return infrastructure.getEntityPersister().createEntityFromStoredType(state, mappingPolicy);
return infrastructure.getEntityPersister().createEntityFromStoredType(state, mappingPolicy, this);
}
@Override
public <S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type, MappingPolicy mappingPolicy) {
notNull(state,"node or relationship",type,"entity class");
return infrastructure.getEntityPersister().createEntityFromState(state, type, mappingPolicy);
return infrastructure.getEntityPersister().createEntityFromState(state, type, mappingPolicy, this);
}
@Override
public <S extends PropertyContainer, T> T load(S state, Class<T> type) {
notNull(state,"node or relationship",type,"entity class");
return infrastructure.getEntityPersister().createEntityFromState(state, type, getMappingPolicy(type));
return infrastructure.getEntityPersister().createEntityFromState(state, type, getMappingPolicy(type), this);
}
@Override
public <T> T projectTo(Object entity, Class<T> targetType) {
notNull(entity,"entity",targetType,"new entity class");
return infrastructure.getEntityPersister().projectTo(entity, targetType);
return infrastructure.getEntityPersister().projectTo(entity, targetType, this);
}
@Override
public <T> T projectTo(Object entity, Class<T> targetType, MappingPolicy mappingPolicy) {
notNull(entity,"entity",targetType,"new entity class");
return infrastructure.getEntityPersister().projectTo(entity, targetType, mappingPolicy);
return infrastructure.getEntityPersister().projectTo(entity, targetType, mappingPolicy, this);
}
/**
@@ -289,12 +282,6 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
return infrastructure.getGraphDatabaseService().beginTx();
}
@SuppressWarnings("unused")
@PostConstruct
public void postConstruct() {
infrastructure.postConstruct();
}
@Override
public boolean isNodeEntity(Class<?> targetType) {
return getMappingContext().isNodeEntity(targetType);
@@ -308,7 +295,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
@Override
@SuppressWarnings("unchecked")
public <T> T save(T entity) {
return (T) infrastructure.getEntityPersister().persist(entity, getMappingPolicy(entity));
return (T) infrastructure.getEntityPersister().persist(entity, getMappingPolicy(entity), this);
}
public boolean isManaged(Object entity) {
@@ -340,7 +327,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
if (relationship == null) return null;
if (Relationship.class.isAssignableFrom(relationshipEntityClass)) return (R)relationship;
final Neo4jPersistentEntityImpl<?> persistentEntity = getPersistentEntity(relationshipEntityClass);
return infrastructure.getEntityPersister().createEntityFromState(relationship, relationshipEntityClass, persistentEntity.getMappingPolicy());
return infrastructure.getEntityPersister().createEntityFromState(relationship, relationshipEntityClass, persistentEntity.getMappingPolicy(), this);
}
@Override
@@ -487,7 +474,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
} else {
final PropertyContainer state = getPersistentState(value);
if (state != null) {
return entityPersister.loadEntity(value, (Node) state, MappingPolicy.LOAD_POLICY, (Neo4jPersistentEntityImpl<T>) getPersistentEntity(targetType));
return entityPersister.loadEntity(value, (Node) state, MappingPolicy.LOAD_POLICY, (Neo4jPersistentEntityImpl<T>) getPersistentEntity(targetType), this);
} else {
// todo do nothing?
throw new MappingException("No state information available in " + value);
@@ -514,7 +501,11 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
@Override
public ResultConverter getDefaultConverter() {
return infrastructure.getResultConverter();
final ResultConverter resultConverter = infrastructure.getResultConverter();
if (resultConverter instanceof Neo4jTemplateAware) {
return ((Neo4jTemplateAware)resultConverter).with(this);
}
return resultConverter;
}
@Override
@@ -642,11 +633,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
return infrastructure.getGraphDatabaseService();
}
public void setInfrastructure(MappingInfrastructure infrastructure) {
this.infrastructure = infrastructure;
}
public MappingInfrastructure getInfrastructure() {
public Infrastructure getInfrastructure() {
return infrastructure;
}

View File

@@ -0,0 +1,26 @@
/**
* 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.data.neo4j.conversion.ResultConverter;
/**
* @author mh
* @since 19.04.12
*/
public interface Neo4jTemplateAware<T,R> {
ResultConverter<T,R> with(Neo4jTemplate template);
}

View File

@@ -19,9 +19,12 @@ package org.springframework.data.neo4j.support.conversion;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.neo4j.annotation.MapResult;
import org.springframework.data.neo4j.conversion.DefaultConverter;
import org.springframework.data.neo4j.conversion.ResultConverter;
import org.springframework.data.neo4j.core.EntityPath;
import org.springframework.data.neo4j.mapping.EntityPersister;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.Neo4jTemplateAware;
import org.springframework.data.neo4j.support.path.ConvertingEntityPath;
import java.lang.reflect.InvocationHandler;
@@ -32,26 +35,34 @@ import java.util.Map;
* @author mh
* @since 28.06.11
*/
public class EntityResultConverter<T, R> extends DefaultConverter<T, R> {
public class EntityResultConverter<T, R> extends DefaultConverter<T, R> implements Neo4jTemplateAware<T,R> {
private final ConversionService conversionService;
private final EntityPersister entityPersister;
public EntityResultConverter(ConversionService conversionService, EntityPersister entityPersister) {
public EntityResultConverter(ConversionService conversionService) {
this.conversionService = conversionService;
this.entityPersister = entityPersister;
}
private static ThreadLocal<Neo4jTemplate> holder = new ThreadLocal<Neo4jTemplate>();
@Override
public ResultConverter<T,R> with(Neo4jTemplate template) {
holder.set(template);
return this;
}
@SuppressWarnings("unchecked")
@Override
protected Object doConvert(Object value, Class<?> sourceType, Class targetType, MappingPolicy mappingPolicy) {
Neo4jTemplate template = holder.get();
if (EntityPath.class.isAssignableFrom(targetType)) {
return new ConvertingEntityPath(entityPersister, toPath(value, sourceType));
return new ConvertingEntityPath(toPath(value, sourceType),template);
}
if (entityPersister.isNodeEntity(targetType)) {
return entityPersister.projectTo(toNode(value, sourceType), targetType, mappingPolicy);
if (template.isNodeEntity(targetType)) {
return template.projectTo(toNode(value, sourceType), targetType, mappingPolicy);
}
if (entityPersister.isRelationshipEntity(targetType)) {
return entityPersister.projectTo(toRelationship(value, sourceType), targetType, mappingPolicy);
if (template.isRelationshipEntity(targetType)) {
return template.projectTo(toRelationship(value, sourceType), targetType, mappingPolicy);
}
final Object result = super.doConvert(value, sourceType, targetType, mappingPolicy);

View File

@@ -19,6 +19,7 @@ import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.helpers.collection.ClosableIterable;
import org.neo4j.helpers.collection.IterableWrapper;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.support.Neo4jTemplate;
/**
* @author mh
@@ -29,18 +30,20 @@ public class EntityCreatingClosableIterable<T> extends IterableWrapper<T,Propert
private final Class<T> entityClass;
private final Neo4jEntityPersister entityPersister;
private final MappingPolicy mappingPolicy;
private final Neo4jTemplate template;
public EntityCreatingClosableIterable(ClosableIterable<PropertyContainer> iterable, Class<T> entityClass, Neo4jEntityPersister entityPersister) {
public EntityCreatingClosableIterable(ClosableIterable<PropertyContainer> iterable, Class<T> entityClass, Neo4jEntityPersister entityPersister, Neo4jTemplate template) {
super(iterable);
this.iterable = iterable;
this.entityClass = entityClass;
this.entityPersister = entityPersister;
this.template = template;
mappingPolicy = this.entityPersister.getMappingPolicy(this.entityClass);
}
@Override
protected T underlyingObjectToObject(PropertyContainer state) {
return entityPersister.createEntityFromState(state, entityClass, mappingPolicy);
return entityPersister.createEntityFromState(state, entityClass, mappingPolicy, template);
}
@Override

View File

@@ -25,6 +25,7 @@ import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.neo4j.mapping.*;
import org.springframework.data.neo4j.mapping.ManagedEntity;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
@@ -66,7 +67,7 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
}
@Override
public <R extends T> R read(Class<R> requestedType, S source, MappingPolicy mappingPolicy) {
public <R extends T> R read(Class<R> requestedType, S source, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
// 1) source -> type alias
// 2) type alias -> type
// 3) check for subtype matching / enforcement
@@ -87,22 +88,22 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
entityStateHandler.setPersistentState(createdEntity,source);
if (persistentEntity.isManaged()) return createdEntity;
loadEntity(createdEntity, source, mappingPolicy, persistentEntity);
loadEntity(createdEntity, source, mappingPolicy, persistentEntity, template);
return createdEntity;
}
@Override
public <R extends T> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity) {
public <R extends T> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity, final Neo4jTemplate template) {
if (mappingPolicy.shouldLoad()) {
final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper = BeanWrapper.create(entity, conversionService);
sourceStateTransmitter.copyPropertiesFrom(wrapper, source, persistentEntity,mappingPolicy);
sourceStateTransmitter.copyPropertiesFrom(wrapper, source, persistentEntity,mappingPolicy, template);
// 6) handle cascading fetches
cascadeFetch(persistentEntity, wrapper, mappingPolicy);
cascadeFetch(persistentEntity, wrapper, mappingPolicy, template);
}
return entity;
}
private <R extends T> void cascadeFetch(Neo4jPersistentEntityImpl<R> persistentEntity, final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, final MappingPolicy policy) {
private <R extends T> void cascadeFetch(Neo4jPersistentEntityImpl<R> persistentEntity, final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, final MappingPolicy policy, final Neo4jTemplate template) {
persistentEntity.doWithAssociations(new AssociationHandler<Neo4jPersistentProperty>() {
@Override
public void doWithAssociation(Association<Neo4jPersistentProperty> association) {
@@ -113,7 +114,7 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
final Object value = getProperty(wrapper, property);
@SuppressWarnings("unchecked") final Neo4jPersistentEntityImpl<Object> persistentEntity =
(Neo4jPersistentEntityImpl<Object>) mappingContext.getPersistentEntity(property.getTypeInformation().getActualType());
final Object fetchedValue = entityFetchHandler.fetch(value, persistentEntity, property, mappingPolicy);
final Object fetchedValue = entityFetchHandler.fetch(value, persistentEntity, property, mappingPolicy, template);
// replace fetched one-time iterables and similiar managed values
sourceStateTransmitter.setProperty(wrapper, property, fetchedValue);
}
@@ -132,7 +133,7 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
}
@Override
public void write(T source, S sink, MappingPolicy mappingPolicy) {
public void write(T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
final Class<?> sourceType = source.getClass();
@SuppressWarnings("unchecked") final Neo4jPersistentEntityImpl<T> persistentEntity = (Neo4jPersistentEntityImpl<T>) mappingContext.getPersistentEntity(sourceType);
if (persistentEntity.isManaged()) { // todo check if typerepreentationstragegy is called ??
@@ -146,7 +147,7 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
entityStateHandler.setPersistentState(source, sink);
typeMapper.writeType(sourceType, sink);
}
sourceStateTransmitter.copyPropertiesTo(wrapper, sink, persistentEntity,mappingPolicy);
sourceStateTransmitter.copyPropertiesTo(wrapper, sink, persistentEntity,mappingPolicy, template);
}
/*
private Node useGetOrCreateNode(S node, Neo4jPersistentEntity<?> persistentEntity, BeanWrapper<Neo4jPersistentEntity<Object>, Object> wrapper) {

View File

@@ -23,6 +23,7 @@ import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.ArrayList;
import java.util.List;
@@ -46,7 +47,7 @@ public class Neo4jEntityFetchHandler {
// todo actually cascade !!
public Object fetch(final Object value, Neo4jPersistentEntity<Object> persistentEntity, Neo4jPersistentProperty property, final MappingPolicy policy) {
public Object fetch(final Object value, Neo4jPersistentEntity<Object> persistentEntity, Neo4jPersistentProperty property, final MappingPolicy policy, final Neo4jTemplate template) {
if (value == null) return value;
//MappingPolicy mappingPolicy = mappingPolicy.combineWith(property.getMappingPolicy());
final MappingPolicy mappingPolicy = property.getMappingPolicy();
@@ -56,7 +57,7 @@ public class Neo4jEntityFetchHandler {
for (Object inner : ((Iterable) value)) {
final BeanWrapper<Neo4jPersistentEntity<Object>, Object> innerWrapper = BeanWrapper.create(inner, conversionService);
final PropertyContainer state = entityStateHandler.getPersistentState(inner);
fetchValue(innerWrapper, state, persistentEntity, mappingPolicy);
fetchValue(innerWrapper, state, persistentEntity, mappingPolicy, template);
replacement.add(inner);
//sourceStateTransmitter.copyPropertiesFrom(innerWrapper, entityStateHandler.<S>getPersistentState(inner), persistentEntity);
}
@@ -64,17 +65,17 @@ public class Neo4jEntityFetchHandler {
} else {
final BeanWrapper<Neo4jPersistentEntity<Object>, Object> innerWrapper = BeanWrapper.create(value, conversionService);
final PropertyContainer state = entityStateHandler.getPersistentState(value);
fetchValue(innerWrapper, state, persistentEntity, mappingPolicy);
fetchValue(innerWrapper, state, persistentEntity, mappingPolicy, template);
// sourceStateTransmitter.copyPropertiesFrom(innerWrapper, entityStateHandler.<S>getPersistentState(value), persistentEntity);
}
return value;
}
public void fetchValue(final BeanWrapper<Neo4jPersistentEntity<Object>, Object> wrapper, PropertyContainer source, Neo4jPersistentEntity<Object> persistentEntity, final MappingPolicy mappingPolicy) {
public void fetchValue(final BeanWrapper<Neo4jPersistentEntity<Object>, Object> wrapper, PropertyContainer source, Neo4jPersistentEntity<Object> persistentEntity, final MappingPolicy mappingPolicy, final Neo4jTemplate template) {
if (persistentEntity.isNodeEntity()) {
nodeStateTransmitter.copyPropertiesFrom(wrapper, (Node) source,persistentEntity, mappingPolicy);
nodeStateTransmitter.copyPropertiesFrom(wrapper, (Node) source,persistentEntity, mappingPolicy, template);
}
if (persistentEntity.isRelationshipEntity()) {
relationshipStateTransmitter.copyPropertiesFrom(wrapper, (Relationship) source, persistentEntity, mappingPolicy);
relationshipStateTransmitter.copyPropertiesFrom(wrapper, (Relationship) source, persistentEntity, mappingPolicy, template);
}
}
}

View File

@@ -21,6 +21,7 @@ import org.neo4j.graphdb.Relationship;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.neo4j.mapping.*;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.HashMap;
import java.util.Map;
@@ -47,12 +48,12 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
}
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy) {
return createEntityFromState(state,null, mappingPolicy);
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
return createEntityFromState(state,null, mappingPolicy, template);
}
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state) {
return createEntityFromState(state,null, null);
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state, final Neo4jTemplate template) {
return createEntityFromState(state,null, null, template);
}
@@ -155,38 +156,38 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
}
@Override
public <R> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity) {
return delegate.loadEntity(entity,source,mappingPolicy,persistentEntity);
public <R> R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity, final Neo4jTemplate template) {
return delegate.loadEntity(entity,source,mappingPolicy,persistentEntity, template);
}
@Override
public <R> R read(Class<R> type, S state, MappingPolicy mappingPolicy) {
public <R> R read(Class<R> type, S state, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
try {
if (state==null) throw new IllegalArgumentException("State must not be null");
StackedEntityCache.push();
if (StackedEntityCache.contains(state, mappingPolicy)) return StackedEntityCache.get(state,mappingPolicy);
return StackedEntityCache.add(state, delegate.read(type, state,mappingPolicy),mappingPolicy);
return StackedEntityCache.add(state, delegate.read(type, state,mappingPolicy, template),mappingPolicy);
} finally {
StackedEntityCache.pop();
}
}
@Override
public void write(Object source, S sink,MappingPolicy mappingPolicy) {
delegate.write(source,sink,mappingPolicy);
public void write(Object source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
delegate.write(source,sink,mappingPolicy, template);
}
}
@SuppressWarnings("unchecked")
public <S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type, MappingPolicy mappingPolicy) {
public <S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
if (state == null) {
throw new IllegalArgumentException("state has to be either a Node or Relationship, but is null");
}
if (isNode(state)) {
return nodeConverter.read(type, (Node) state,mappingPolicy);
return nodeConverter.read(type, (Node) state,mappingPolicy, template);
}
if (isRelationship(state)) {
return relationshipConverter.read(type, (Relationship) state,mappingPolicy);
return relationshipConverter.read(type, (Relationship) state,mappingPolicy, template);
}
throw new IllegalArgumentException("state has to be either a Node or Relationship");
}
@@ -199,18 +200,18 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
return state instanceof Node;
}
public <T> T projectTo(Object entity, Class<T> targetType) {
return projectTo(entity,targetType,getMappingPolicy(targetType));
public <T> T projectTo(Object entity, Class<T> targetType, final Neo4jTemplate template) {
return projectTo(entity,targetType,getMappingPolicy(targetType), template);
}
@SuppressWarnings("unchecked")
public <T> T projectTo(Object entity, Class<T> targetType, MappingPolicy mappingPolicy) {
public <T> T projectTo(Object entity, Class<T> targetType, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
if (targetType.isInstance(entity)) {
return (T)entity;
}
PropertyContainer state = getPersistentState(entity);
final MappingPolicy newPolicy = mappingPolicy == null ? getMappingPolicy(targetType) : mappingPolicy;
return createEntityFromState(state, targetType, newPolicy);
return createEntityFromState(state, targetType, newPolicy, template);
}
@SuppressWarnings("unchecked")
@@ -219,12 +220,12 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
}
public Object persist(Object entity, final MappingPolicy mappingPolicy) {
public Object persist(Object entity, final MappingPolicy mappingPolicy, final Neo4jTemplate template) {
final Class<?> type = entity.getClass();
if (isManaged(entity)) {
return ((ManagedEntity)entity).persist();
} else {
return persist(entity, type, mappingPolicy);
return persist(entity, type, mappingPolicy, template);
}
}
@@ -232,17 +233,17 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
return entityStateHandler.isManaged(entity);
}
private Object persist(Object entity, Class<?> type,MappingPolicy mappingPolicy) {
private Object persist(Object entity, Class<?> type, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
if (isNodeEntity(type)) {
final Node node = this.<Node>getPersistentState(entity);
this.nodeConverter.write(entity, node,mappingPolicy);
return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type));
this.nodeConverter.write(entity, node,mappingPolicy, template);
return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type), template);
//return entity; // TODO ?
}
if (isRelationshipEntity(type)) {
final Relationship relationship = this.<Relationship>getPersistentState(entity);
this.relationshipConverter.write(entity, relationship,mappingPolicy);
return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type));
this.relationshipConverter.write(entity, relationship,mappingPolicy, template);
return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type), template);
// return entity; // TODO ?
}
throw new IllegalArgumentException("@NodeEntity or @RelationshipEntity annotation required on domain class"+type);
@@ -280,18 +281,18 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
}
@Override
public <R> R read(Class<R> type, Node source, MappingPolicy mappingPolicy) {
return createEntityFromState(source, type, mappingPolicy);
public <R> R read(Class<R> type, Node source, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
return createEntityFromState(source, type, mappingPolicy, template);
}
@Override
public <R> R loadEntity(R entity, Node source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity) {
return nodeConverter.loadEntity(entity,source,mappingPolicy,persistentEntity);
public <R> R loadEntity(R entity, Node source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl<R> persistentEntity, final Neo4jTemplate template) {
return nodeConverter.loadEntity(entity,source,mappingPolicy,persistentEntity, template);
}
@Override
public void write(Object source, Node sink, MappingPolicy mappingPolicy) {
nodeConverter.write(source,sink,mappingPolicy);
public void write(Object source, Node sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
nodeConverter.write(source,sink,mappingPolicy, template);
}
}

View File

@@ -43,12 +43,12 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
this.entityStateFactory = entityStateFactory;
}
public <R> R copyPropertiesFrom(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S source, Neo4jPersistentEntity<R> persistentEntity, final MappingPolicy mappingPolicy) {
public <R> R copyPropertiesFrom(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S source, Neo4jPersistentEntity<R> persistentEntity, final MappingPolicy mappingPolicy, final Neo4jTemplate template) {
final R entity = wrapper.getBean();
/* final Transaction tx = getTemplate().beginTx();
try {
*/
final EntityState<S> entityState = entityStateFactory.getEntityState(entity, false);
final EntityState<S> entityState = entityStateFactory.getEntityState(entity, false, template);
entityState.setPersistentState(source);
// entityState.persist();
persistentEntity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
@@ -78,10 +78,6 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
entityState.setValue(property, value, mappingPolicy);
}
private Neo4jTemplate getTemplate() {
return entityStateFactory.getTemplate();
}
private <T> T getProperty(BeanWrapper<Neo4jPersistentEntity<Object>, Object> wrapper, Neo4jPersistentProperty property, Class<T> type, boolean fieldAccessOnly) {
return wrapper.getProperty(property, type, fieldAccessOnly);
}
@@ -112,11 +108,11 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
return value;
}
public <R> void copyPropertiesTo(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S target, Neo4jPersistentEntity<R> persistentEntity, MappingPolicy mappingPolicy) {
final Transaction tx = getTemplate().beginTx();
public <R> void copyPropertiesTo(final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, S target, Neo4jPersistentEntity<R> persistentEntity, MappingPolicy mappingPolicy, final Neo4jTemplate template) {
final Transaction tx = template.beginTx();
try {
//final Node targetNode = useGetOrCreateNode(node, persistentEntity, wrapper);
final EntityState<S> entityState = entityStateFactory.getEntityState(wrapper.getBean(), false);
final EntityState<S> entityState = entityStateFactory.getEntityState(wrapper.getBean(), false, template);
entityState.setPersistentState(target);
entityState.persist();
// todo take mapping policies for attributes into account

View File

@@ -24,7 +24,5 @@ import org.springframework.data.neo4j.support.Neo4jTemplate;
* @since 07.10.11
*/
public interface EntityStateFactory<S extends PropertyContainer> {
EntityState<S> getEntityState(final Object entity, boolean detachable);
Neo4jTemplate getTemplate();
EntityState<S> getEntityState(final Object entity, boolean detachable, Neo4jTemplate template);
}

View File

@@ -19,52 +19,32 @@ package org.springframework.data.neo4j.support.node;
import org.neo4j.graphdb.Node;
import org.springframework.data.neo4j.core.EntityState;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.DetachedEntityState;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.support.Neo4jTemplate;
public class NodeEntityStateFactory implements EntityStateFactory<Node> {
protected Neo4jTemplate template;
protected final FieldAccessorFactoryFactory nodeDelegatingFieldAccessorFactory;
protected final Neo4jMappingContext mappingContext;
protected DelegatingFieldAccessorFactory nodeDelegatingFieldAccessorFactory;
public NodeEntityStateFactory(Neo4jMappingContext mappingContext, FieldAccessorFactoryFactory nodeDelegatingFieldAccessorFactory) {
this.nodeDelegatingFieldAccessorFactory = nodeDelegatingFieldAccessorFactory;
this.mappingContext = mappingContext;
}
protected Neo4jMappingContext mappingContext;
public EntityState<Node> getEntityState(final Object entity, boolean detachable) {
public EntityState<Node> getEntityState(final Object entity, boolean detachable, Neo4jTemplate template) {
final Class<?> entityType = entity.getClass();
@SuppressWarnings("unchecked") final Neo4jPersistentEntity<Object> persistentEntity =
(Neo4jPersistentEntity<Object>) mappingContext.getPersistentEntity(entityType);
NodeEntityState nodeEntityState = new NodeEntityState(null, entity, entityType, template,
nodeDelegatingFieldAccessorFactory, persistentEntity);
nodeDelegatingFieldAccessorFactory.provideFactoryFor(template), persistentEntity);
if (!detachable) {
return nodeEntityState;
}
return new DetachedEntityState<Node>(nodeEntityState, template);
}
public void setNodeDelegatingFieldAccessorFactory(
DelegatingFieldAccessorFactory nodeDelegatingFieldAccessorFactory) {
this.nodeDelegatingFieldAccessorFactory = nodeDelegatingFieldAccessorFactory;
}
public void setTemplate(Neo4jTemplate template) {
this.template = template;
}
public Neo4jMappingContext getMappingContext() {
return mappingContext;
}
public void setMappingContext(Neo4jMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
public Neo4jTemplate getTemplate() {
return template;
}
}

View File

@@ -24,6 +24,7 @@ import org.neo4j.helpers.collection.IterableWrapper;
import org.springframework.data.neo4j.core.EntityPath;
import org.springframework.data.neo4j.mapping.EntityPersister;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.Iterator;
@@ -34,6 +35,8 @@ import java.util.Iterator;
@SuppressWarnings("unchecked") // TODO DefaultNode/RelationshipBacked
public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
private final Neo4jTemplate template;
@Override
public <T> T startEntity(Class<T>... types) {
return projectEntityToFirstParameterOrCreateFromStoredType(startNode(), types);
@@ -41,8 +44,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 persister.createEntityFromStoredType(node, MappingPolicy.LOAD_POLICY);
return persister.projectTo(node, types[0]);
if (types==null || types.length==0) return template.createEntityFromStoredType(node, MappingPolicy.LOAD_POLICY);
return template.projectTo(node, types[0]);
}
@Override
@@ -53,7 +56,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 persister.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, types));
return template.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, types));
}
private static <T> T getFirstOrDefault(final T defaultValue, T... values) {
@@ -66,7 +69,7 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,Node>(nodes()) {
@Override
protected T underlyingObjectToObject(Node node) {
return persister.createEntityFromStoredType(node, null);
return template.createEntityFromStoredType(node, null);
}
};
}
@@ -76,7 +79,7 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,Relationship>(relationships()) {
@Override
protected T underlyingObjectToObject(Relationship relationship) {
return persister.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
return template.projectTo(relationship, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
}
};
}
@@ -86,18 +89,17 @@ public class ConvertingEntityPath<S,E> implements EntityPath<S,E> {
return new IterableWrapper<T,PropertyContainer>(delegate) {
@Override
protected T underlyingObjectToObject(PropertyContainer element) {
return persister.projectTo(element, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
return template.projectTo(element, getFirstOrDefault((Class<T>) DefaultRelationshipBacked.class, relationships));
}
};
}
public ConvertingEntityPath(EntityPersister persister, Path delegate) {
this.persister = persister;
public ConvertingEntityPath(Path delegate, Neo4jTemplate template) {
this.delegate = delegate;
this.template = template;
}
private final EntityPersister persister;
private final Path delegate;
@Override

View File

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

View File

@@ -36,7 +36,7 @@ public abstract class EntityMapper<S, E, T> implements PathMapper<T> {
@Override
public T mapPath(Path path) {
return mapPath(new ConvertingEntityPath<S,E>(template, path));
return mapPath(new ConvertingEntityPath<S,E>(path, template));
}
public abstract static class WithoutResult<S,E> extends EntityMapper<S,E,Void> {

View File

@@ -35,6 +35,6 @@ public class EntityPathPathIterableWrapper<S, E> extends IterableWrapper<EntityP
}
protected EntityPath<S, E> underlyingObjectToObject(Path path) {
return new ConvertingEntityPath<S,E>(template,path);
return new ConvertingEntityPath<S,E>(path, template);
}
}

View File

@@ -33,7 +33,7 @@ public class ConversionServiceQueryResultConverter<R> extends DefaultConverter<O
@SuppressWarnings("unchecked")
@Override
protected Object doConvert(Object value, Class<?> sourceType, Class type, MappingPolicy mappingPolicy) {
public Object doConvert(Object value, Class<?> sourceType, Class type, MappingPolicy mappingPolicy) {
if (conversionService.canConvert(sourceType, type)) {
return conversionService.convert(value, type);
}

View File

@@ -20,6 +20,7 @@ import org.neo4j.graphdb.Relationship;
import org.springframework.data.neo4j.core.EntityState;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.DetachedEntityState;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
@@ -27,38 +28,24 @@ import org.springframework.data.neo4j.support.node.EntityStateFactory;
public class RelationshipEntityStateFactory implements EntityStateFactory<Relationship> {
private Neo4jTemplate template;
private DelegatingFieldAccessorFactory relationshipDelegatingFieldAccessorFactory;
private Neo4jMappingContext mappingContext;
private final FieldAccessorFactoryFactory relationshipDelegatingFieldAccessorFactory;
private final Neo4jMappingContext mappingContext;
public RelationshipEntityStateFactory(Neo4jMappingContext mappingContext, FieldAccessorFactoryFactory relationshipDelegatingFieldAccessorFactory) {
this.mappingContext = mappingContext;
this.relationshipDelegatingFieldAccessorFactory = relationshipDelegatingFieldAccessorFactory;
}
@SuppressWarnings("unchecked")
public EntityState<Relationship> getEntityState(final Object entity, boolean detachable) {
public EntityState<Relationship> getEntityState(final Object entity, boolean detachable, Neo4jTemplate template) {
final Class<?> entityType = entity.getClass();
final Neo4jPersistentEntity persistentEntity = (Neo4jPersistentEntity) mappingContext.getPersistentEntity(entityType);
final RelationshipEntityState relationshipEntityState = new RelationshipEntityState(null, entity, entityType, template, relationshipDelegatingFieldAccessorFactory, persistentEntity);
final DelegatingFieldAccessorFactory fieldAccessorFactory = relationshipDelegatingFieldAccessorFactory.provideFactoryFor(template);
final RelationshipEntityState relationshipEntityState = new RelationshipEntityState(null, entity, entityType, template, fieldAccessorFactory, persistentEntity);
if (!detachable) {
return relationshipEntityState;
}
return new DetachedEntityState<Relationship>(relationshipEntityState, template);
}
public void setTemplate(Neo4jTemplate template) {
this.template = template;
}
public void setRelationshipDelegatingFieldAccessorFactory(
DelegatingFieldAccessorFactory delegatingFieldAccessorFactory) {
this.relationshipDelegatingFieldAccessorFactory = delegatingFieldAccessorFactory;
}
public void setMappingContext(Neo4jMappingContext mappingContext) {
this.mappingContext = mappingContext;
}
@Override
public Neo4jTemplate getTemplate() {
return template;
}
}

View File

@@ -17,18 +17,11 @@ package org.springframework.data.neo4j.mapping;
import org.junit.Test;
import org.mockito.Mockito;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.springframework.data.neo4j.model.BestFriend;
import org.springframework.data.neo4j.model.Friendship;
import org.springframework.data.neo4j.model.Person;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -44,7 +37,7 @@ public class Neo4jEntityPersisterTest extends Neo4jPersistentTestBase {
public void testCreateEntityFromStoredType() throws Exception {
final Node personNode = template.createNode();
personNode.setProperty("name","Michael");
final Person person = entityPersister.createEntityFromState(personNode, Person.class, template.getMappingPolicy(Person.class));
final Person person = entityPersister.createEntityFromState(personNode, Person.class, template.getMappingPolicy(Person.class), template);
assertEquals("Michael",person.getName());
}
@@ -56,7 +49,7 @@ public class Neo4jEntityPersisterTest extends Neo4jPersistentTestBase {
@Test
public void testProjectTo() throws Exception {
storeInGraph(michael);
final Developer developer = entityPersister.projectTo(michael, Developer.class);
final Developer developer = entityPersister.projectTo(michael, Developer.class, template);
assertEquals(michael.getId(), developer.id);
assertEquals(michael.getName(), developer.name);
}
@@ -69,7 +62,7 @@ public class Neo4jEntityPersisterTest extends Neo4jPersistentTestBase {
@Test
public void testPersist() throws Exception {
entityPersister.persist(michael, template.getMappingPolicy(michael));
entityPersister.persist(michael, template.getMappingPolicy(michael), template);
assertEquals((Long) michaelNode().getId(), michael.getId());
assertEquals(michaelNode(), entityPersister.getPersistentState(michael));
assertEquals(michaelNode().getProperty("name"), michael.getName());

View File

@@ -25,15 +25,19 @@ import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.TypeMapper;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
import org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean;
import org.springframework.data.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
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.MappingInfrastructure;
import org.springframework.data.neo4j.support.Infrastructure;
import org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.mapping.*;
import org.springframework.data.neo4j.support.node.EntityStateFactory;
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
@@ -56,8 +60,6 @@ import static java.util.Arrays.asList;
public class Neo4jPersistentTestBase {
private Transaction tx;
protected Neo4jTemplate template;
protected NodeEntityStateFactory nodeEntityStateFactory;
protected RelationshipEntityStateFactory relationshipEntityStateFactory;
protected EntityStateHandler entityStateHandler;
protected NodeEntityInstantiator nodeEntityInstantiator;
protected RelationshipEntityInstantiator relationshipEntityInstantiator;
@@ -88,30 +90,10 @@ public class Neo4jPersistentTestBase {
public void setUp() throws Exception {
// todo cleanup !!
mappingContext = new Neo4jMappingContext();
MappingInfrastructure infrastructure = createInfrastructure(mappingContext);
Infrastructure infrastructure = createInfrastructure(mappingContext);
template = new Neo4jTemplate(infrastructure);
nodeEntityStateFactory = createNodeEntityStateFactory(mappingContext);
relationshipEntityStateFactory = createRelationshipEntityStateFactory(mappingContext);
infrastructure.setNodeEntityStateFactory(nodeEntityStateFactory);
infrastructure.setRelationshipEntityStateFactory(relationshipEntityStateFactory);
template.postConstruct();
entityStateHandler = infrastructure.getEntityStateHandler();
nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler);
relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler);
nodeTypeMapper = new DefaultTypeMapper<Node>(new TRSTypeAliasAccessor<Node>(infrastructure.getNodeTypeRepresentationStrategy()), asList(new ClassValueTypeInformationMapper()));
nodeStateTransmitter = new SourceStateTransmitter<Node>(nodeEntityStateFactory);
relationshipStateTransmitter = new SourceStateTransmitter<Relationship>(relationshipEntityStateFactory);
conversionService = template.getConversionService();
fetchHandler = new Neo4jEntityFetchHandler(entityStateHandler, conversionService, nodeStateTransmitter, relationshipStateTransmitter);
final EntityTools<Node> nodeEntityTools = new EntityTools<Node>(infrastructure.getNodeTypeRepresentationStrategy(), nodeEntityStateFactory, nodeEntityInstantiator, mappingContext);
final EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(infrastructure.getRelationshipTypeRepresentationStrategy(), relationshipEntityStateFactory, relationshipEntityInstantiator, mappingContext);
entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
tx = template.beginTx();
group = new Group();
@@ -120,35 +102,50 @@ public class Neo4jPersistentTestBase {
andres = new Person("Andrés", 36);
}
private NodeEntityStateFactory createNodeEntityStateFactory(Neo4jMappingContext mappingContext) {
final NodeEntityStateFactory nodeEntityStateFactory = new NodeEntityStateFactory();
nodeEntityStateFactory.setMappingContext(mappingContext);
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(template);
relationshipEntityStateFactory.setRelationshipDelegatingFieldAccessorFactory(new RelationshipDelegatingFieldAccessorFactory(template));
return relationshipEntityStateFactory;
}
private MappingInfrastructure createInfrastructure(Neo4jMappingContext mappingContext) throws Exception {
MappingInfrastructure infrastructure = new MappingInfrastructure();
private Infrastructure createInfrastructure(Neo4jMappingContext mappingContext) throws Exception {
MappingInfrastructureFactoryBean factoryBean = new MappingInfrastructureFactoryBean();
final GraphDatabaseService gdb = new ImpermanentGraphDatabase();
infrastructure.setGraphDatabaseService(gdb);
factoryBean.setGraphDatabaseService(gdb);
final DelegatingGraphDatabase graphDatabase = new DelegatingGraphDatabase(gdb);
infrastructure.setGraphDatabase(graphDatabase);
infrastructure.setMappingContext(mappingContext);
factoryBean.setGraphDatabase(graphDatabase);
factoryBean.setMappingContext(mappingContext);
final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase);
infrastructure.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy());
infrastructure.setRelationshipTypeRepresentationStrategy(new NoopRelationshipTypeRepresentationStrategy());
infrastructure.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
infrastructure.setEntityStateHandler(entityStateHandler);
return infrastructure;
final NoopNodeTypeRepresentationStrategy nodeTypeRepresentationStrategy = new NoopNodeTypeRepresentationStrategy();
factoryBean.setNodeTypeRepresentationStrategy(nodeTypeRepresentationStrategy);
final NoopRelationshipTypeRepresentationStrategy relationshipTypeRepresentationStrategy = new NoopRelationshipTypeRepresentationStrategy();
factoryBean.setRelationshipTypeRepresentationStrategy(relationshipTypeRepresentationStrategy);
factoryBean.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
factoryBean.setEntityStateHandler(entityStateHandler);
EntityStateFactory<Node> nodeEntityStateFactory = new NodeEntityStateFactory(mappingContext, new FieldAccessorFactoryFactory() {
public DelegatingFieldAccessorFactory create(Neo4jTemplate template) {
return new NodeDelegatingFieldAccessorFactory(template);
}
});
EntityStateFactory<Relationship> relationshipEntityStateFactory = new RelationshipEntityStateFactory(mappingContext, new FieldAccessorFactoryFactory() {
public DelegatingFieldAccessorFactory create(Neo4jTemplate template) {
return new RelationshipDelegatingFieldAccessorFactory(template);
}
});
factoryBean.setNodeEntityStateFactory(nodeEntityStateFactory);
factoryBean.setRelationshipEntityStateFactory(relationshipEntityStateFactory);
nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler);
relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler);
nodeTypeMapper = new DefaultTypeMapper<Node>(new TRSTypeAliasAccessor<Node>(nodeTypeRepresentationStrategy), asList(new ClassValueTypeInformationMapper()));
nodeStateTransmitter = new SourceStateTransmitter<Node>(nodeEntityStateFactory);
relationshipStateTransmitter = new SourceStateTransmitter<Relationship>(relationshipEntityStateFactory);
fetchHandler = new Neo4jEntityFetchHandler(entityStateHandler, conversionService, nodeStateTransmitter, relationshipStateTransmitter);
final EntityTools<Node> nodeEntityTools = new EntityTools<Node>(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator, mappingContext);
final EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator, mappingContext);
entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
protected List<Node> groupMemberNodes() {
@@ -195,7 +192,7 @@ public class Neo4jPersistentTestBase {
}
protected Object write(Object entity, Node node) {
entityPersister.write(entity, node, template.getMappingPolicy(entity));
entityPersister.write(entity, node, template.getMappingPolicy(entity), template);
return entity;
}
@@ -225,7 +222,7 @@ public class Neo4jPersistentTestBase {
}
public Person readPerson(Node node) {
return entityPersister.read(Person.class, node, template.getMappingPolicy(Person.class));
return entityPersister.read(Person.class, node, template.getMappingPolicy(Person.class), template);
}
protected Relationship makeFriends(Node from, Node to, int years) {
@@ -235,7 +232,7 @@ public class Neo4jPersistentTestBase {
}
public Group readGroup(Node node) {
return entityPersister.read(Group.class, node,template.getMappingPolicy(Group.class));
return entityPersister.read(Group.class, node,template.getMappingPolicy(Group.class), template);
}
protected List<Node> getRelatedNodes(Node startNode, String type, Direction direction) {

View File

@@ -70,7 +70,6 @@ public class Neo4jTemplateApiTest {
transactionManager = createTransactionManager();
referenceNode = graphDatabase.getReferenceNode();
template = new Neo4jTemplate(graphDatabase, transactionManager);
template.postConstruct(); // todo defaults
createData();
}

View File

@@ -44,7 +44,6 @@ public abstract class NeoApiTest {
graph = createGraphDatabase();
transactionManager = createTransactionManager();
template = new Neo4jTemplate(graph, transactionManager);
template.postConstruct();
}
private ConversionService createConversionService() throws Exception {

View File

@@ -56,7 +56,6 @@ public class SnippetNeo4jTemplateMethodsTest extends DocumentingTestBase {
// SNIPPET template
// TODO auto-post-construct !!
final Neo4jTemplate neo = new Neo4jTemplate(graphDatabase);
neo.postConstruct();
Node mark = neo.createNode(map("name", "Mark"));
Node thomas = neo.createNode(map("name", "Thomas"));

View File

@@ -106,7 +106,7 @@ public void foo( @Context WorldRepository repo ) {
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>
]]></programlisting>
</example>

View File

@@ -27,11 +27,16 @@ class Person {
The validation supports needs the bean validation API and a reference implementation configured, right now this is the Hibernate Validator by default (which not integrated with Hibernate ORM). Tthe maven dependency is:
</para>
<example>
<title>Hibernate Validator Dependency</title>
<title>Validation setup</title>
<programlisting language="java"><![CDATA[<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>]]></programlisting>
</dependency>
// the application-context should contain a LocalValidatorFactoryBean
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>]]></programlisting>
</example>
</section>

View File

@@ -26,7 +26,8 @@
</para>
<para>
Numerical fields are indexed numerically so that they are available for range queries. All
other fields are indexed with their string representation.
other fields are indexed with their string representation. If a numeric field should not be
indexed numerically, it is possible to switch it off with <code>@Indexed(numeric=false)</code>.
</para>
<para>
The <code>@Indexed</code> annotation also provides the option of using a custom index name. The default index

View File

@@ -17,15 +17,15 @@
<section>
<title>Dependencies for Spring Data Neo4j Simple Mapping</title>
<para>
For the simple POJO mapping it is enough to add the <code>org.springframework.data:spring-data-neo4j:2.0.0.RELEASE</code> dependency
to your project. If you want to use the Cypher query language please add <code>org.neo4j:neo4j-cypher:1.6</code>
For the simple POJO mapping it is enough to add the <code>org.springframework.data:spring-data-neo4j:2.1.0.RC1</code> dependency
to your project. If you want to use the Cypher query language please add <code>org.neo4j:neo4j-cypher:1.7</code>
</para>
<example>
<title>Maven dependencies for Spring Data Neo4j</title>
<programlisting language="xml"><![CDATA[<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>
]]></programlisting>
</example>
@@ -44,7 +44,7 @@
targetCompatibility = 1.6
springVersion = "3.0.7.RELEASE"
springDataNeo4jVersion = "2.0.0.RELEASE"
springDataNeo4jVersion = "2.1.0.RC1"
aspectjVersion = "1.6.12"
apply from:'https://github.com/SpringSource/spring-data-neo4j/raw/master/build/
@@ -128,7 +128,7 @@ repositories {
<programlisting language="xml"><![CDATA[<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-aspects</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>
<dependency>
@@ -139,7 +139,7 @@ repositories {
[<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher</artifactId>
<version>1.6</version>
<version>1.7</version>
</dependency>]
]]></programlisting>
</example>

View File

@@ -48,7 +48,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>
]]></programlisting>
</example>

View File

@@ -40,7 +40,7 @@
<programlisting language="xml" ><![CDATA[<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>1.6</version>
<version>1.7</version>
</dependency>
]]></programlisting>
</example>

View File

@@ -26,7 +26,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-aspects</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>
<dependency>

View File

@@ -21,7 +21,7 @@
<programlisting language="xml"><![CDATA[<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.0.RC1</version>
</dependency>]]></programlisting>
</example>
</para>