diff --git a/spring-data-neo4j-aspects/src/main/aspect/org/springframework/data/neo4j/aspects/support/node/Neo4jNodeBacking.aj b/spring-data-neo4j-aspects/src/main/aspect/org/springframework/data/neo4j/aspects/support/node/Neo4jNodeBacking.aj index 98e68ef72..7548e2874 100644 --- a/spring-data-neo4j-aspects/src/main/aspect/org/springframework/data/neo4j/aspects/support/node/Neo4jNodeBacking.aj +++ b/spring-data-neo4j-aspects/src/main/aspect/org/springframework/data/neo4j/aspects/support/node/Neo4jNodeBacking.aj @@ -160,7 +160,7 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix } public T NodeBacked.projectTo(Class targetType) { - return (T)graphDatabaseContext().projectTo( this, targetType); + return (T) template().projectTo( this, targetType); } public Relationship NodeBacked.relateTo(NodeBacked target, String type) { @@ -172,7 +172,7 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix } public Relationship NodeBacked.getRelationshipTo(NodeBacked target, String type) { - return graphDatabaseContext().getRelationshipTo(this,target,null,type); + return template().getRelationshipBetween(this, target, null, type); } public Long NodeBacked.getNodeId() { @@ -182,51 +182,50 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix public Iterable NodeBacked.findAllByTraversal(final Class targetType, TraversalDescription traversalDescription) { if (!hasPersistentState()) throw new IllegalStateException("No node attached to " + this); - final Traverser traverser = traversalDescription.traverse(this.getPersistentState()); - return graphDatabaseContext().convertResultsTo(traverser, targetType); + return template().traverse(this.getPersistentState(), traversalDescription).to(targetType); } public Iterable NodeBacked.findAllByQuery(final String query, final Class targetType, Map params) { - final CypherQueryExecutor executor = new CypherQueryExecutor(graphDatabaseContext()); + final CypherQueryExecutor executor = new CypherQueryExecutor(template()); return executor.query(query, targetType,params); } public Iterable> NodeBacked.findAllByQuery(final String query,Map params) { - final CypherQueryExecutor executor = new CypherQueryExecutor(graphDatabaseContext()); + final CypherQueryExecutor executor = new CypherQueryExecutor(template()); return executor.queryForList(query,params); } public T NodeBacked.findByQuery(final String query, final Class targetType,Map params) { - final CypherQueryExecutor executor = new CypherQueryExecutor(graphDatabaseContext()); + final CypherQueryExecutor executor = new CypherQueryExecutor(template()); return executor.queryForObject(query, targetType,params); } public Iterable> NodeBacked.findAllPathsByTraversal(TraversalDescription traversalDescription) { if (!hasPersistentState()) throw new IllegalStateException("No node attached to " + this); final Traverser traverser = traversalDescription.traverse(this.getPersistentState()); - return new EntityPathPathIterableWrapper(traverser, graphDatabaseContext()); + return new EntityPathPathIterableWrapper(traverser, template()); } public R NodeBacked.relateTo(N target, Class relationshipClass, String relationshipType) { - return graphDatabaseContext().relateTo(this, target, relationshipClass, relationshipType, false); + return template().createRelationshipBetween(this, target, relationshipClass, relationshipType, false); } public R NodeBacked.relateTo(N target, Class relationshipClass, String relationshipType, boolean allowDuplicates) { - return graphDatabaseContext().relateTo(this,target,relationshipClass, relationshipType,allowDuplicates); + return template().createRelationshipBetween(this, target, relationshipClass, relationshipType, allowDuplicates); } public void NodeBacked.remove() { - graphDatabaseContext().removeNodeEntity(this); + template().removeNodeEntity(this); } public void NodeBacked.removeRelationshipTo(NodeBacked target, String relationshipType) { - graphDatabaseContext().removeRelationshipTo(this,target,relationshipType); + template().removeRelationshipBetween(this, target, relationshipType); } public R NodeBacked.getRelationshipTo( NodeBacked target, Class relationshipClass, String type) { - return (R)graphDatabaseContext().getRelationshipTo(this,target,relationshipClass,type); + return (R) template().getRelationshipBetween(this, target, relationshipClass, type); } - public static Neo4jTemplate graphDatabaseContext() { + public static Neo4jTemplate template() { return Neo4jNodeBacking.aspectOf().template; } @@ -239,7 +238,7 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix } public static EntityStateHandler entityStateHandler() { - return graphDatabaseContext().getEntityStateHandler(); + return template().getEntityStateHandler(); } /** diff --git a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityInstantiationTest.java b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityInstantiationTest.java index 901bc0370..661860429 100644 --- a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityInstantiationTest.java +++ b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityInstantiationTest.java @@ -46,7 +46,7 @@ public class NodeEntityInstantiationTest extends EntityTestBase { Person p = persistedPerson("Rod", 39); long nodeId = getNodeId(p); - Node node = neo4jTemplate.getNodeById(nodeId); + Node node = neo4jTemplate.getNode(nodeId); Person person1 = (Person) neo4jTemplate.createEntityFromStoredType(node); assertEquals("Rod", person1.getName()); Person person2 = neo4jTemplate.createEntityFromState(node,Person.class); diff --git a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityRelationshipTest.java b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityRelationshipTest.java index af755146e..747fea40b 100644 --- a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityRelationshipTest.java +++ b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityRelationshipTest.java @@ -232,9 +232,9 @@ public class NodeEntityRelationshipTest extends EntityTestBase { public void multipleRelationshipsOfSameTypeBetweenTwoEntities() { Person michael = persistedPerson("Michael", 35); Person david = persistedPerson("David", 25); - Friendship friendship1 = neo4jTemplate.relateTo(michael,david, Friendship.class, "knows", true); + Friendship friendship1 = neo4jTemplate.createRelationshipBetween(michael, david, Friendship.class, "knows", true); friendship1.setYears(1); - Friendship friendship2 = neo4jTemplate.relateTo(michael,david, Friendship.class, "knows",true); + Friendship friendship2 = neo4jTemplate.createRelationshipBetween(michael, david, Friendship.class, "knows", true); friendship2.setYears(2); assertTrue("two different relationships", friendship1 != friendship2); assertTrue("two different relationships", getRelationshipState(friendship1) != getRelationshipState(friendship2)); diff --git a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityTest.java b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityTest.java index f642b7d0e..388fefbec 100644 --- a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityTest.java +++ b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/NodeEntityTest.java @@ -19,8 +19,8 @@ package org.springframework.data.neo4j.aspects.support; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.neo4j.graphdb.NotFoundException; import org.neo4j.graphdb.Transaction; +import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.neo4j.aspects.Attribute; import org.springframework.data.neo4j.aspects.Group; import org.springframework.data.neo4j.aspects.Person; @@ -42,7 +42,7 @@ public class NodeEntityTest extends EntityTestBase { Person p = persistedPerson("Rod", 39); assertEquals(p.getName(), getNodeState(p).getProperty("name")); assertEquals(p.getAge(), getNodeState(p).getProperty("age")); - Person found = neo4jTemplate.createEntityFromState(neo4jTemplate.getNodeById(getNodeId(p)), Person.class); + Person found = neo4jTemplate.createEntityFromState(neo4jTemplate.getNode(getNodeId(p)), Person.class); assertEquals("Rod", getNodeState(found).getProperty("name")); assertEquals(39, getNodeState(found).getProperty("age")); } @@ -79,7 +79,7 @@ public class NodeEntityTest extends EntityTestBase { assertEquals("developers", getNodeState(group).getProperty("name")); } // own transaction handling because of http://wiki.neo4j.org/content/Delete_Semantics - @Test(expected = NotFoundException.class) + @Test(expected = DataRetrievalFailureException.class) public void testDeleteEntityFromGDC() { Transaction tx = neo4jTemplate.beginTx(); Person p = persistedPerson("Michael", 35); @@ -92,10 +92,10 @@ public class NodeEntityTest extends EntityTestBase { Assert.assertNull("spouse removed " + p.getSpouse(), p.getSpouse()); Person spouseFromIndex = personRepository.findByPropertyValue(Person.NAME_INDEX, "name", "Tina"); Assert.assertNull("spouse not found in index",spouseFromIndex); - Assert.assertNull("node deleted " + id, neo4jTemplate.getNodeById(id)); + Assert.assertNull("node deleted " + id, neo4jTemplate.getNode(id)); } - @Test(expected = NotFoundException.class) + @Test(expected = DataRetrievalFailureException.class) public void testDeleteEntity() { Transaction tx = neo4jTemplate.beginTx(); Person p = persistedPerson("Michael", 35); @@ -108,7 +108,7 @@ public class NodeEntityTest extends EntityTestBase { Assert.assertNull("spouse removed " + p.getSpouse(), p.getSpouse()); Person spouseFromIndex = personRepository.findByPropertyValue(Person.NAME_INDEX, "name", "Tina"); Assert.assertNull("spouse not found in index", spouseFromIndex); - Assert.assertNull("node deleted " + id, neo4jTemplate.getNodeById(id)); + Assert.assertNull("node deleted " + id, neo4jTemplate.getNode(id)); } @Test diff --git a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/RelationshipEntityTest.java b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/RelationshipEntityTest.java index 33092fd7a..e9251422f 100644 --- a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/RelationshipEntityTest.java +++ b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/RelationshipEntityTest.java @@ -96,7 +96,7 @@ public class RelationshipEntityTest extends EntityTestBase { Person p = persistedPerson("Michael", 35); Person p2 = persistedPerson("David", 25); Friendship f = p.knows(p2); - assertEquals(f, neo4jTemplate.getRelationshipTo(p,p2, Friendship.class, "knows")); + assertEquals(f, neo4jTemplate.getRelationshipBetween(p, p2, Friendship.class, "knows")); } @Test diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/DefaultConverter.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/DefaultConverter.java index 2fdf9f762..8152dedc8 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/DefaultConverter.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/DefaultConverter.java @@ -43,6 +43,7 @@ public class DefaultConverter implements ResultConverter { } protected Object extractValue(Object value) { + if (value instanceof Path) return value; // todo is this sensible to do? if (value instanceof Map) return extractSingle(((Map)value).values()); if (value instanceof Iterable) return extractSingle((Iterable)value); return value; @@ -76,6 +77,7 @@ public class DefaultConverter implements ResultConverter { protected 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; } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/Result.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/Result.java index 9a76cac55..162be74da 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/Result.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/Result.java @@ -20,7 +20,7 @@ package org.springframework.data.neo4j.conversion; * @author mh * @since 28.06.11 */ -public interface Result extends Iterable, EndResult { +public interface Result extends EndResult { EndResult to(Class type); EndResult to(Class type, ResultConverter resultConverter); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/TraverserConverter.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/TraverserConverter.java deleted file mode 100644 index 705a51b0e..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/TraverserConverter.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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.conversion; - -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Path; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.traversal.Traverser; -import org.neo4j.helpers.collection.IterableWrapper; -import org.springframework.data.neo4j.core.EntityPath; -import org.springframework.data.neo4j.support.Neo4jTemplate; -import org.springframework.data.neo4j.support.path.EntityPathPathIterableWrapper; - -/** - * @author mh - * @since 16.10.11 - */ // todo integrate in result conversion handling -public class TraverserConverter { - - private final Neo4jTemplate ctx; - - public TraverserConverter(Neo4jTemplate ctx) { - this.ctx = ctx; - } - - @SuppressWarnings("unchecked") - public Iterable convert(Traverser traverser, Class targetType) { - if (Node.class.isAssignableFrom(targetType)) return (Iterable) traverser.nodes(); - if (Relationship.class.isAssignableFrom(targetType)) return (Iterable) traverser.relationships(); - if (EntityPath.class.isAssignableFrom(targetType)) return new EntityPathPathIterableWrapper(traverser, ctx); - if (Path.class.isAssignableFrom(targetType)) return (Iterable) traverser; - return (Iterable) convertToGraphEntity(traverser, targetType); - } - - private Iterable convertToGraphEntity(Traverser traverser, final Class targetType) { - if (ctx.isNodeEntity(targetType)) { - return new IterableWrapper(traverser.nodes()) { - @Override - protected Object underlyingObjectToObject(Node node) { - return ctx.createEntityFromState(node, targetType); - } - }; - } - if (ctx.isRelationshipEntity(targetType)) { - return new IterableWrapper(traverser.relationships()) { - @Override - protected Object underlyingObjectToObject(Relationship relationship) { - return ctx.createEntityFromState(relationship, targetType); - } - }; - } - throw new IllegalStateException("Can't determine valid type for traversal target " + targetType); - - } -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/SourceStateTransmitter.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/SourceStateTransmitter.java index f4e95712e..d6a1f1a7a 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/SourceStateTransmitter.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/SourceStateTransmitter.java @@ -151,7 +151,7 @@ public class SourceStateTransmitter { return newNode; } try { - return getGraphDatabaseContext().getNodeById(id); + return getGraphDatabaseContext().getNode(id); } catch (NotFoundException nfe) { throw new MappingException("Could not find node with id " + id); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java index ced288617..ecfae678e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java @@ -25,6 +25,7 @@ import org.neo4j.graphdb.index.IndexHits; import org.neo4j.graphdb.index.ReadableIndex; import org.neo4j.helpers.collection.ClosableIterable; import org.neo4j.helpers.collection.IterableWrapper; +import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -93,7 +94,7 @@ public abstract class AbstractGraphRepository im public T findOne(final Long id) { try { return createEntity(getById(id)); - } catch (NotFoundException e) { + } catch (DataRetrievalFailureException e) { return null; } } @@ -248,7 +249,7 @@ public abstract class AbstractGraphRepository im public boolean exists(Long id) { try { return getById(id)!=null; - } catch (NotFoundException e) { + } catch (DataRetrievalFailureException e) { return false; } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/NodeGraphRepository.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/NodeGraphRepository.java index 27750a125..960eca7d1 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/NodeGraphRepository.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/NodeGraphRepository.java @@ -29,7 +29,7 @@ public class NodeGraphRepository extends AbstractGraphRepository imp @Override protected Node getById(long id) { - return template.getNodeById(id); + return template.getNode(id); } @Override diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/RelationshipGraphRepository.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/RelationshipGraphRepository.java index 00986d61a..050ae8f6c 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/RelationshipGraphRepository.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/RelationshipGraphRepository.java @@ -30,7 +30,7 @@ public class RelationshipGraphRepository extends AbstractGraphRepository type = entity.getClass(); + if (entityStateHandler.isNodeEntity(type)) { + removeNodeEntity(entity); + return; + } + if (entityStateHandler.isRelationshipEntity(type)) { + removeRelationshipEntity(entity); + return; + } + throw new IllegalArgumentException("@NodeEntity or @RelationshipEntity annotation required on domain class"+type); + } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java index f4b5bb671..0611951e3 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java @@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFactory; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.traversal.TraversalDescription; -import org.neo4j.graphdb.traversal.Traverser; import org.neo4j.helpers.collection.ClosableIterable; import org.springframework.core.convert.ConversionService; import org.springframework.dao.DataAccessException; @@ -33,12 +32,9 @@ import org.springframework.data.neo4j.annotation.RelationshipEntity; import org.springframework.data.neo4j.conversion.QueryResultBuilder; import org.springframework.data.neo4j.conversion.Result; import org.springframework.data.neo4j.conversion.ResultConverter; -import org.springframework.data.neo4j.conversion.TraverserConverter; -import org.springframework.data.neo4j.core.EntityPath; 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.Neo4jEntityPersister; import org.springframework.data.neo4j.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.mapping.Neo4jPersistentEntityImpl; @@ -48,7 +44,6 @@ import org.springframework.data.neo4j.repository.RelationshipGraphRepository; import org.springframework.data.neo4j.support.conversion.EntityResultConverter; import org.springframework.data.neo4j.support.node.EntityStateFactory; import org.springframework.data.neo4j.support.node.NodeEntityInstantiator; -import org.springframework.data.neo4j.support.path.EntityPathPathIterableWrapper; import org.springframework.data.neo4j.support.query.CypherQueryExecutor; import org.springframework.data.neo4j.support.query.QueryEngine; import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator; @@ -110,7 +105,7 @@ public class Neo4jTemplate implements Neo4jOperations { } /** - * @param graphDatabase the neo4j graph database + * @param graphDatabase the neo4j graph database * @param transactionManager if passed in, will be used to create implicit transactions whenever needed */ public Neo4jTemplate(final GraphDatabase graphDatabase, PlatformTransactionManager transactionManager) { @@ -130,7 +125,7 @@ public class Neo4jTemplate implements Neo4jOperations { public GraphRepository repositoryFor(Class clazz) { if (isNodeEntity(clazz)) return new NodeGraphRepository(clazz, this); if (isRelationshipEntity(clazz)) return new RelationshipGraphRepository(clazz, this); - throw new IllegalArgumentException("Can't create graph repository for non graph entity of type "+clazz); + throw new IllegalArgumentException("Can't create graph repository for non graph entity of type " + clazz); } public GraphDatabase getGraphDatabase() { @@ -156,8 +151,8 @@ public class Neo4jTemplate implements Neo4jOperations { @SuppressWarnings("unchecked") public Index getIndex(Class type, String indexName, Boolean fullText) { - if (type==null) { - notNull(indexName,"indexName"); + if (type == null) { + notNull(indexName, "indexName"); return getIndex(indexName); } @@ -172,7 +167,8 @@ public class Neo4jTemplate implements Neo4jOperations { } if (persistentEntity.isNodeEntity()) return (Index) createIndex(Node.class, indexName, fullText); - if (persistentEntity.isRelationshipEntity()) return (Index) createIndex(Relationship.class, indexName, fullText); + if (persistentEntity.isRelationshipEntity()) + return (Index) createIndex(Relationship.class, indexName, fullText); throw new IllegalArgumentException("Wrong index type supplied: " + type + " expected Node- or Relationship-Entity"); } @@ -184,19 +180,20 @@ public class Neo4jTemplate implements Neo4jOperations { public boolean isNode(Class type) { if (type.equals(Node.class)) return true; if (type.equals(Relationship.class)) return false; - throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship"+type); + throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship" + type); } // TODO handle existing indexes @SuppressWarnings("unchecked") public Index createIndex(Class type, String indexName, boolean fullText) { - return graphDatabase.createIndex(type,indexName,fullText); + return graphDatabase.createIndex(type, indexName, fullText); } } public Index getIndex(Class type) { return indexProvider.getIndex(type, null); } + public Index getIndex(String name) { return indexProvider.getIndex(null, name); } @@ -207,7 +204,7 @@ public class Neo4jTemplate implements Neo4jOperations { @SuppressWarnings("unchecked") public Index getIndex(Class type, String indexName, Boolean fullText) { - return indexProvider.getIndex(type,indexName,fullText); + return indexProvider.getIndex(type, indexName, fullText); } /** @@ -245,7 +242,7 @@ public class Neo4jTemplate implements Neo4jOperations { // todo depending on type of mapping @SuppressWarnings("unchecked") - public T setPersistentState(T entity, S state) { + public T setPersistentState(T entity, S state) { entityPersister.setPersistentState(entity, state); return entity; } @@ -256,25 +253,9 @@ public class Neo4jTemplate implements Neo4jOperations { } public void remove(Object entity) { - if (entity instanceof Node) { - ((Node)entity).delete(); - return; - } - if (entity instanceof Relationship) { - ((Relationship)entity).delete(); - return; - } - final Class type = entity.getClass(); - if (isNodeEntity(type)) { - entityRemover.removeNodeEntity(entity); - return; - } - if (isRelationshipEntity(type)) { - entityRemover.removeRelationshipEntity(entity); - return; - } - throw new IllegalArgumentException("@NodeEntity or @RelationshipEntity annotation required on domain class"+type); + entityRemover.remove(entity); } + public void removeNodeEntity(Object entity) { entityRemover.removeNodeEntity(entity); } @@ -292,44 +273,43 @@ public class Neo4jTemplate implements Neo4jOperations { } @Override - public Node createNode(final Map properties) { + public Node createNode(final Map properties) { return graphDatabase.createNode(properties); } - public T createNode(Class target, Map properties) { + public T createNode(Class target, Map properties) { final Node node = createNode(properties); if (isNodeEntity(target)) { - typeRepresentationStrategies.postEntityCreation(node,target); + typeRepresentationStrategies.postEntityCreation(node, target); } return convert(node, target); } - public Result createNodes(Map...allNodes) { - Collection result=new ArrayList(allNodes.length); - for (Map properties : allNodes) { + public Result createNodes(Map firstNode, Map... otherNodes) { + Collection result = new ArrayList(otherNodes.length + 1); + result.add(createNode(firstNode)); + for (Map properties : otherNodes) { result.add(createNode(properties)); } return convert(result); } - public Iterable createNodes(Class target, Map...allNodes) { + public Iterable createNodes(Class target, Map firstNode, Map... otherNodes) { final TypeRepresentationStrategy nodeTypeRepresentationStrategy = isNodeEntity(target) ? typeRepresentationStrategies.getNodeTypeRepresentationStrategy() : null; - Collection result=new ArrayList(allNodes.length); - for (Map properties : allNodes) { - final Node node = createNode(properties); - if (nodeTypeRepresentationStrategy!=null) { - nodeTypeRepresentationStrategy.postEntityCreation(node,target); - } - result.add(node); + Collection result = new ArrayList(otherNodes.length + 1); + result.add(createNode(firstNode, target, nodeTypeRepresentationStrategy)); + for (Map properties : otherNodes) { + result.add(createNode(properties, target, nodeTypeRepresentationStrategy)); } return convert(result).to(target); } - /** - * Delegates to {@link GraphDatabaseService} - */ - public Node getNodeById(final long nodeId) { - return graphDatabase.getNodeById(nodeId); + private Node createNode(Map properties, Class target, TypeRepresentationStrategy nodeTypeRepresentationStrategy) { + final Node node = createNode(properties); + if (nodeTypeRepresentationStrategy != null) { + nodeTypeRepresentationStrategy.postEntityCreation(node, target); + } + return node; } /** @@ -339,33 +319,26 @@ public class Neo4jTemplate implements Neo4jOperations { return graphDatabaseService.beginTx(); } - /** - * Delegates to {@link GraphDatabaseService} - */ - public Relationship getRelationshipById(final long id) { - return graphDatabase.getRelationshipById(id); - } - @PostConstruct public Neo4jTemplate postConstruct() { this.resultConverter = new EntityResultConverter(this); - if (this.graphDatabase==null) { - this.graphDatabase=new DelegatingGraphDatabase(graphDatabaseService,resultConverter); + if (this.graphDatabase == null) { + this.graphDatabase = new DelegatingGraphDatabase(graphDatabaseService, resultConverter); } this.typeRepresentationStrategies = new TypeRepresentationStrategies(mappingContext, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy); this.cypherQueryExecutor = new CypherQueryExecutor(this); final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase); - if (nodeEntityInstantiator==null) { + if (nodeEntityInstantiator == null) { nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler); } EntityTools nodeEntityTools = new EntityTools(nodeTypeRepresentationStrategy, nodeEntityStateFactory, nodeEntityInstantiator); - if (relationshipEntityInstantiator==null) { + if (relationshipEntityInstantiator == null) { relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler); } EntityTools relationshipEntityTools = new EntityTools(relationshipTypeRepresentationStrategy, relationshipEntityStateFactory, relationshipEntityInstantiator); - this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools,mappingContext, entityStateHandler); + this.entityPersister = new Neo4jEntityPersister(conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler); this.entityRemover = new EntityRemover(this.entityStateHandler, nodeTypeRepresentationStrategy, relationshipTypeRepresentationStrategy, graphDatabase); - this.indexProvider = new IndexProvider(mappingContext,graphDatabase); + this.indexProvider = new IndexProvider(mappingContext, graphDatabase); return this; } @@ -380,7 +353,7 @@ public class Neo4jTemplate implements Neo4jOperations { @SuppressWarnings("unchecked") public T save(T entity) { - return (T)entityPersister.persist(entity); + return (T) entityPersister.persist(entity); } public boolean isManaged(Object entity) { @@ -399,34 +372,17 @@ public class Neo4jTemplate implements Neo4jOperations { return cypherQueryExecutor.queryForObject(statement, targetType, params); } - // todo have an result converter that is able to handle iterable input and output types - @SuppressWarnings("unchecked") - public Iterable convertResultsTo(Traverser traverser, Class targetType) { - if (Node.class.isAssignableFrom(targetType)) return (Iterable) traverser.nodes(); - if (Relationship.class.isAssignableFrom(targetType)) return (Iterable) traverser.relationships(); - if (EntityPath.class.isAssignableFrom(targetType)) return new EntityPathPathIterableWrapper(traverser,this); - if (Path.class.isAssignableFrom(targetType)) return (Iterable) traverser; - if (isNodeEntity(targetType)) { - return GraphBackedEntityIterableWrapper.create(traverser.nodes(), targetType, this); - } - if (isRelationshipEntity(targetType)) { - return GraphBackedEntityIterableWrapper.create(traverser.relationships(), targetType, this); - } - throw new IllegalStateException("Can't determine valid type for traversal target " + targetType); - } - - - public R getRelationshipTo(Object source, Object target, Class relationshipClass, String type) { + public R getRelationshipBetween(Object source, Object target, Class relationshipClass, String type) { final Relationship relationship = entityStateHandler.getRelationshipTo(source, target, type); if (relationship == null) return null; return entityPersister.createEntityFromState(relationship, relationshipClass); } - public void removeRelationshipTo(Object start, Object target, String type) { + public void removeRelationshipBetween(Object start, Object target, String type) { entityRemover.removeRelationshipTo(start, target, type); } - public R relateTo(Object source, Object target, Class relationshipClass, String relationshipType, boolean allowDuplicates) { + public R createRelationshipBetween(Object source, Object target, Class relationshipClass, String relationshipType, boolean allowDuplicates) { final RelationshipResult result = entityStateHandler.relateTo(source, target, relationshipType, allowDuplicates); if (result.type == RelationshipResult.Type.NEW) { // TODO @@ -436,7 +392,7 @@ public class Neo4jTemplate implements Neo4jOperations { } @Override - public Relationship createRelationship(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Map properties) { + public Relationship createRelationshipBetween(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Map properties) { notNull(startNode, "startNode", endNode, "endNode", relationshipType, "relationshipType", properties, "properties"); return exec(new GraphCallback() { @Override @@ -446,9 +402,6 @@ public class Neo4jTemplate implements Neo4jOperations { }); } - - - private final Neo4jExceptionTranslator exceptionTranslator = new Neo4jExceptionTranslator(); private static void notNull(Object... pairs) { @@ -464,7 +417,7 @@ public class Neo4jTemplate implements Neo4jOperations { if (ex instanceof RuntimeException) { return exceptionTranslator.translateExceptionIfPossible((RuntimeException) ex); } - return new UncategorizedGraphStoreException("Error executing callback",ex); + return new UncategorizedGraphStoreException("Error executing callback", ex); } @@ -520,7 +473,7 @@ public class Neo4jTemplate implements Neo4jOperations { @Override public T index(final String indexName, final T element, final String field, final Object value) { - notNull(element, "element", field, "field", value, "value",indexName,"indexName"); + notNull(element, "element", field, "field", value, "value", indexName, "indexName"); exec(new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { @@ -540,27 +493,29 @@ public class Neo4jTemplate implements Neo4jOperations { @Override @SuppressWarnings("unchecked") public Result convert(Iterable iterable) { - return new QueryResultBuilder(iterable, (ResultConverter) resultConverter); + return new QueryResultBuilder(iterable, (ResultConverter) resultConverter); } @Override @SuppressWarnings("unchecked") public T convert(Object value, Class type) { - return (T) resultConverter.convert(value,type); + return (T) resultConverter.convert(value, type); } + @Override public QueryEngine queryEngineFor(QueryType type) { - return graphDatabase.queryEngineFor(type,resultConverter); + return graphDatabase.queryEngineFor(type, resultConverter); } + @Override @SuppressWarnings("unchecked") public Result> query(String statement, Map params) { notNull(statement, "statement"); return queryEngineFor(QueryType.Cypher).query(statement, params); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public Result execute(String statement, Map params) { notNull(statement, "statement"); return queryEngineFor(QueryType.Gremlin).query(statement, params); @@ -568,19 +523,14 @@ public class Neo4jTemplate implements Neo4jOperations { @Override public Result traverse(Object start, TraversalDescription traversal) { - return traverse((Node)getPersistentState(start),traversal); + return traverse((Node) getPersistentState(start), traversal); } // TODO result handling !! @SuppressWarnings("unchecked") public Iterable findAllByTraversal(Object entity, Class targetType, TraversalDescription traversalDescription) { - final PropertyContainer state = entityPersister.getPersistentState(entity); - if (state instanceof Node) { - final Traverser traverser = traversalDescription.traverse((Node) state); - return new TraverserConverter(this).convert(traverser, (Class) targetType); - } - throw new IllegalStateException("No node attached to " + entity); + return traverse(entity, traversalDescription).to((Class) targetType); } @Override @@ -603,6 +553,7 @@ public class Neo4jTemplate implements Neo4jOperations { throw translateExceptionIfPossible(e); } } + @Override public Result lookup(final Class indexedType, final Object query) { notNull(query, "valueOrQueryObject", indexedType, "indexedType"); @@ -613,6 +564,7 @@ public class Neo4jTemplate implements Neo4jOperations { throw translateExceptionIfPossible(e); } } + @Override public Result lookup(String indexName, Object query) { notNull(query, "valueOrQueryObject", indexName, "indexName"); @@ -625,9 +577,6 @@ public class Neo4jTemplate implements Neo4jOperations { } - - - public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } @@ -706,4 +655,3 @@ public class Neo4jTemplate implements Neo4jOperations { this.graphDatabase = graphDatabase; } } - diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/conversion/EntityResultConverter.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/conversion/EntityResultConverter.java index 673740336..dc1a1c34d 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/conversion/EntityResultConverter.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/conversion/EntityResultConverter.java @@ -27,25 +27,25 @@ import org.springframework.data.neo4j.support.path.ConvertingEntityPath; * @since 28.06.11 */ public class EntityResultConverter extends DefaultConverter { - private final Neo4jTemplate ctx; + private final Neo4jTemplate template; private final ConversionService conversionService; - public EntityResultConverter(Neo4jTemplate ctx) { - this.ctx = ctx; - conversionService = this.ctx.getConversionService(); + public EntityResultConverter(Neo4jTemplate template) { + this.template = template; + conversionService = this.template.getConversionService(); } @SuppressWarnings("unchecked") @Override protected Object doConvert(Object value, Class sourceType, Class targetType) { - if (ctx.isNodeEntity(targetType)) { - return ctx.projectTo(toNode(value, sourceType), targetType); + if (template.isNodeEntity(targetType)) { + return template.projectTo(toNode(value, sourceType), targetType); } - if (ctx.isRelationshipEntity(targetType)) { - return ctx.projectTo(toRelationship(value, sourceType), targetType); + if (template.isRelationshipEntity(targetType)) { + return template.projectTo(toRelationship(value, sourceType), targetType); } if (EntityPath.class.isAssignableFrom(targetType)) { - return new ConvertingEntityPath(ctx,toPath(value,sourceType)); + return new ConvertingEntityPath(template,toPath(value,sourceType)); } final Object result = super.doConvert(value, sourceType, targetType); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/node/NodeEntityState.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/node/NodeEntityState.java index 63f6736bc..d2cbe647c 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/node/NodeEntityState.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/node/NodeEntityState.java @@ -48,7 +48,7 @@ public class NodeEntityState extends DefaultEntityState { try { final Object id = getIdFromEntity(); if (id instanceof Number) { - final Node node = template.getNodeById(((Number) id).longValue()); + final Node node = template.getNode(((Number) id).longValue()); setPersistentState(node); if (log.isInfoEnabled()) log.info("Entity reattached " + entity.getClass() + "; used Node [" + getPersistentState() + "];"); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/relationship/RelationshipEntityState.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/relationship/RelationshipEntityState.java index 3816e66b1..e2cf18e53 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/relationship/RelationshipEntityState.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/relationship/RelationshipEntityState.java @@ -47,7 +47,7 @@ public class RelationshipEntityState extends DefaultEntityState { try { final Object id = getIdFromEntity(); if (id instanceof Number) { - final Relationship relationship = template.getRelationshipById(((Number) id).longValue()); + final Relationship relationship = template.getRelationship(((Number) id).longValue()); setPersistentState(relationship); if (log.isInfoEnabled()) log.info("Entity reattached " + entity.getClass() + "; used Relationship [" + state + "];"); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java index 06e162bb9..3217b6bed 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java @@ -18,7 +18,9 @@ package org.springframework.data.neo4j.template; import org.neo4j.graphdb.*; import org.neo4j.graphdb.traversal.TraversalDescription; +import org.springframework.data.neo4j.annotation.QueryType; import org.springframework.data.neo4j.conversion.Result; +import org.springframework.data.neo4j.support.query.QueryEngine; import java.util.Map; @@ -78,7 +80,7 @@ public interface Neo4jOperations { * @param props optional initial properties * @return the newly created relationship */ - Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Map props); + Relationship createRelationshipBetween(Node startNode, Node endNode, RelationshipType type, Map props); /** * Indexes the given field and value for the element. @@ -143,4 +145,6 @@ public interface Neo4jOperations { * @return the reference node of the underlying graph database */ T getReferenceNode(Class target); + + QueryEngine queryEngineFor(QueryType type); } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java index b6c65c72f..8cbbd7d84 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java @@ -165,7 +165,7 @@ public class Neo4jPersistentTestBase { } protected Node michaelNode() { - return gdc.getNodeById(michael.getId()); + return gdc.getNode(michael.getId()); } protected Node createNewNode() { @@ -175,7 +175,7 @@ public class Neo4jPersistentTestBase { protected Group storeInGraph(Group g) { final Long id = g.getId(); if (id != null) { - write(g, gdc.getNodeById(id)); + write(g, gdc.getNode(id)); } else { write(g, null); } @@ -185,7 +185,7 @@ public class Neo4jPersistentTestBase { protected Person storeInGraph(Person p) { final Long id = p.getId(); if (id != null) { - write(p, gdc.getNodeById(id)); + write(p, gdc.getNode(id)); } else { write(p,null); } @@ -203,7 +203,7 @@ public class Neo4jPersistentTestBase { } protected Node groupNode() { - return gdc.getNodeById(group.getId()); + return gdc.getNode(group.getId()); } protected Set set(T... objs) { @@ -215,11 +215,11 @@ public class Neo4jPersistentTestBase { } protected Node andresNode() { - return gdc.getNodeById(andres.getId()); + return gdc.getNode(andres.getId()); } protected Node emilNode() { - return gdc.getNodeById(emil.getId()); + return gdc.getNode(emil.getId()); } public Person readPerson(Node node) { diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/GraphDatabaseContextTemplateTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/GraphDatabaseContextTemplateTest.java index dd2dbc07b..03c97e82b 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/GraphDatabaseContextTemplateTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/GraphDatabaseContextTemplateTest.java @@ -315,7 +315,7 @@ public class GraphDatabaseContextTemplateTest { @Test public void shouldCreateRelationshipWithProperty() throws Exception { - Relationship relationship = neo4jTemplate.createRelationship(referenceNode, node1, HAS, map("name", "rel2")); + Relationship relationship = neo4jTemplate.createRelationshipBetween(referenceNode, node1, HAS, map("name", "rel2")); assertNotNull(relationship); assertEquals(referenceNode, relationship.getStartNode()); assertEquals(node1, relationship.getEndNode()); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java index 9652b1d5b..177b1f805 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java @@ -35,7 +35,6 @@ import org.springframework.data.neo4j.support.DelegatingGraphDatabase; import org.springframework.data.neo4j.support.Neo4jTemplate; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.jta.JtaTransactionManager; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; @@ -319,7 +318,7 @@ public class Neo4jTemplateApiTest { @Test public void shouldCreateRelationshipWithProperty() throws Exception { - Relationship relationship = template.createRelationship(referenceNode, node1, HAS,map("name", "rel2")); + Relationship relationship = template.createRelationshipBetween(referenceNode, node1, HAS, map("name", "rel2")); assertNotNull(relationship); assertEquals(referenceNode, relationship.getStartNode()); assertEquals(node1,relationship.getEndNode()); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/test/snippets/SnippetNeo4jTemplateMethodsTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/test/snippets/SnippetNeo4jTemplateMethodsTest.java index 0c47414c2..88a6b9499 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/test/snippets/SnippetNeo4jTemplateMethodsTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/test/snippets/SnippetNeo4jTemplateMethodsTest.java @@ -61,7 +61,7 @@ public class SnippetNeo4jTemplateMethodsTest extends DocumentingTestBase { Node mark = neo.createNode(map("name", "Mark")); Node thomas = neo.createNode(map("name", "Thomas")); - neo.createRelationship(mark, thomas, WORKS_WITH, map("project", "spring-data")); + neo.createRelationshipBetween(mark, thomas, WORKS_WITH, map("project", "spring-data")); neo.index("devs", thomas, "name", "Thomas"); // Cypher TODO