documented and cleaned up Neo4jOperations and fixed Neo4jNodeBacking.getRelationshipTo

This commit is contained in:
Michael Hunger
2011-10-17 16:28:58 +02:00
parent bfc502e458
commit 6a9318bf28
7 changed files with 120 additions and 35 deletions

View File

@@ -159,12 +159,12 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
return this.relateTo(target, type, false);
}
public Relationship NodeBacked.relateTo(NodeBacked target, String type, boolean allowDuplicates) {
final RelationshipResult result = entityStateHandler().relateTo(this, target, type, allowDuplicates);
final RelationshipResult result = entityStateHandler().createRelationshipBetween(this, target, type, allowDuplicates);
return result.relationship;
}
public Relationship NodeBacked.getRelationshipTo(NodeBacked target, String type) {
return template().getRelationshipBetween(this, target, null, type);
return template().getRelationshipBetween(this,target,type);
}
public Long NodeBacked.getNodeId() {

View File

@@ -101,7 +101,7 @@ public class RelationshipEntityTest extends EntityTestBase {
assertEquals(f, neo4jTemplate.getRelationshipBetween(p, p2, Friendship.class, "knows"));
}
@Ignore("The NodeBacking.getRelationshipTo() method is broken at the moment")
//@Ignore("The NodeBacking.getRelationshipTo() method is broken at the moment")
@Test
@Transactional
public void testGetRelationshipTo() {

View File

@@ -8,13 +8,13 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd ">
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">
<context:annotation-config />
<context:spring-configured/>
<neo4j:config storeDirectory="target/neo4j-db"/>
<neo4j:repositories base-package="org.neo4j.examples.imdb.domain" graph-database-context-ref="template"/>
<neo4j:repositories base-package="org.neo4j.examples.imdb.domain"/>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

View File

@@ -59,7 +59,7 @@ public class EntityRemover {
graphDatabase.remove(relationship);
}
public void removeRelationshipTo(Object start, Object target, String type) {
public void removeRelationshipBetween(Object start, Object target, String type) {
final RelationshipResult result = entityStateHandler.removeRelationshipTo(start, target, type);
if (result!=null && result.type == RelationshipResult.Type.DELETED) {
relationshipTypeRepresentationStrategy.preEntityRemoval(result.relationship);

View File

@@ -132,17 +132,17 @@ public class EntityStateHandler {
}
public RelationshipResult relateTo(Object source, Object target, String type) {
return this.relateTo(source, target, type, false);
return this.createRelationshipBetween(source, target, type, false);
}
// todo gdc.postEntityCreation(rel), return createEntityFromState(rel)
public RelationshipResult relateTo(Object source, Object target, String type, boolean allowDuplicates) {
public RelationshipResult createRelationshipBetween(Object source, Object target, String type, boolean allowDuplicates) {
if (source == null) throw new IllegalArgumentException("Source entity is null");
if (target == null) throw new IllegalArgumentException("Target entity is null");
if (type == null) throw new IllegalArgumentException("Relationshiptype is null");
if (!allowDuplicates) {
Relationship relationship = getRelationshipTo(source, target, type);
Relationship relationship = getRelationshipBetween(source, target, type);
if (relationship != null) return new RelationshipResult(relationship, RelationshipResult.Type.EXISTING);
}
@@ -164,7 +164,7 @@ public class EntityStateHandler {
}
public RelationshipResult removeRelationshipTo(Object source, Object target, String relationshipType) {
final Relationship relationship = getRelationshipTo(source, target, relationshipType);
final Relationship relationship = getRelationshipBetween(source, target, relationshipType);
if (relationship!=null) {
relationship.delete();
return new RelationshipResult(relationship, RelationshipResult.Type.DELETED);
@@ -172,7 +172,7 @@ public class EntityStateHandler {
return null;
}
public Relationship getRelationshipTo(Object source, Object target, String type) {
public Relationship getRelationshipBetween(Object source, Object target, String type) {
if (source == null) throw new IllegalArgumentException("Source entity is null");
if (target == null) throw new IllegalArgumentException("Target entity is null");
if (type == null) throw new IllegalArgumentException("Relationshiptype is null");

View File

@@ -219,21 +219,19 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
public Result<Node> createNodes(Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
Collection<Node> result = new ArrayList<Node>(otherNodes.length + 1);
result.add(createNode(firstNode));
for (Map<String, Object> properties : otherNodes) {
public Result<Node> createNodes(Map<String, Object>... allProperties) {
Collection<Node> result = new ArrayList<Node>(allProperties.length);
for (Map<String, Object> properties : allProperties) {
result.add(createNode(properties));
}
return convert(result);
}
@Override
public <T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
public <T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object>... allProperties) {
final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy = isNodeEntity(target) ? infrastructure.getTypeRepresentationStrategies().getNodeTypeRepresentationStrategy() : null;
Collection<Node> result = new ArrayList<Node>(otherNodes.length + 1);
result.add(createNode(firstNode, target, nodeTypeRepresentationStrategy));
for (Map<String, Object> properties : otherNodes) {
Collection<Node> result = new ArrayList<Node>(allProperties.length);
for (Map<String, Object> properties : allProperties) {
result.add(createNode(properties, target, nodeTypeRepresentationStrategy));
}
return convert(result).to(target);
@@ -279,7 +277,6 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
return infrastructure.getEntityStateHandler().isManaged(entity);
}
@Override
public Object query(String statement, Map<String, Object> params, final TypeInformation<?> typeInformation) {
final TypeInformation<?> actualType = typeInformation.getActualType();
final Class<?> targetType = actualType.getType();
@@ -295,21 +292,27 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
@Override
public <R> R getRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType) {
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
final Relationship relationship = infrastructure.getEntityStateHandler().getRelationshipTo(start, end, relationshipType);
final Relationship relationship = infrastructure.getEntityStateHandler().getRelationshipBetween(start, end, relationshipType);
if (relationship == null) return null;
if (Relationship.class.isAssignableFrom(relationshipEntityClass)) return (R)relationship;
return infrastructure.getEntityPersister().createEntityFromState(relationship, relationshipEntityClass);
}
@Override
public Relationship getRelationshipBetween(Object start, Object end, String relationshipType) {
notNull(start,"start",end,"end",relationshipType,"relationshipType");
return infrastructure.getEntityStateHandler().getRelationshipBetween(start,end,relationshipType);
}
@Override
public void removeRelationshipBetween(Object start, Object end, String type) {
notNull(start,"start",end,"end",type,"relationshipType");
infrastructure.getEntityRemover().removeRelationshipTo(start, end, type);
infrastructure.getEntityRemover().removeRelationshipBetween(start, end, type);
}
@Override
public <R> R createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates) {
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
final RelationshipResult result = infrastructure.getEntityStateHandler().relateTo(start, end, relationshipType, allowDuplicates);
final RelationshipResult result = infrastructure.getEntityStateHandler().createRelationshipBetween(start, end, relationshipType, allowDuplicates);
if (result.type == RelationshipResult.Type.NEW) {
// TODO
postEntityCreation(result.relationship, relationshipEntityClass);
@@ -360,9 +363,12 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
@SuppressWarnings("unchecked")
public <T> T getReferenceNode(Class<T> target) {
try {
return convert(infrastructure.getGraphDatabase().getReferenceNode(), target);
final Node node = infrastructure.getGraphDatabase().getReferenceNode();
if (Node.class.isAssignableFrom(target)) return (T) node;
return convert(node, target);
} catch (RuntimeException e) {
throw translateExceptionIfPossible(e);
}
@@ -444,7 +450,6 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
@SuppressWarnings("unchecked")
public <T> Iterable<T> traverse(Object entity, Class<?> targetType, TraversalDescription traversalDescription) {
notNull(entity,"entity",targetType,"target type",traversalDescription,"traversal description");

View File

@@ -24,7 +24,6 @@ import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.conversion.Result;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.support.query.QueryEngine;
import org.springframework.data.util.TypeInformation;
import java.util.Map;
@@ -60,15 +59,34 @@ public interface Neo4jOperations {
*/
Node getNode(long id);
Node createNode(Map<String, Object> props);
/**
* Creates a node
* @param properties the properties that should be initially set on the node
*/
Node createNode(Map<String, Object> properties);
Node createNode();
/**
* Creates a node mapped by the given entity class
* @param target mapped entity class or Node.class
* @param properties the properties that should be initially set on the node
*/
<T> T createNodeAs(Class<T> target, Map<String, Object> properties);
Result<Node> createNodes(Map<String, Object> firstNode, Map<String, Object>... otherNodes);
/**
* Creates a number of nodes in a single step
* @param allProperties
* @return the nodes as a Result, which can be converted
*/
Result<Node> createNodes(Map<String, Object>... allProperties);
<T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes);
/**
* Creates a number of nodes mapped by the given entity class
* @param target mapped entity class or Node.class
* @param allProperties properties for each of the created nodes
*/
<T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object>... allProperties);
/**
@@ -80,22 +98,48 @@ public interface Neo4jOperations {
*/
Relationship getRelationship(long id);
/**
* Creates a relationship with the given initial properties.
*/
Relationship createRelationshipBetween(Node startNode, Node endNode, RelationshipType type, Map<String, Object> props);
/**
* Retrieves a single relationship entity between two node entities with the given relationship type projected to the provided
* relationship entity class
*/
<R> R getRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType);
/**
* Retrieves a single relationship entity between two node entities.
*/
Relationship getRelationshipBetween(Object start, Object end, String relationshipType);
/**
* Removes the relationship of this type between the two node entities
*/
void removeRelationshipBetween(Object start, Object end, String type);
/**
* Creates a single relationship entity between two node entities with the given relationship type projected to the provided
* relationship entity class. If it allowDuplicates existing relationships won't be taken into account. Returns the projected
* relationship entity.
*/
<R> R createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates);
/**
* Retrieves an existing index for the given class and/or name
* @param type entity class, might be null
* @param indexName might be null
* @return Index&lt;Node%gt; or Index&lt;Relationship&gt;
*/
<S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName);
/**
* Indexes the given field and value for the element.
*
* @param indexName Name of the index, will be checked against existing indexes according to the given element
* assumes a "node" node index or "relationship" relationship index for a null value
* assumes a "node" node index or "relationship" relationship index for a null value
* @param element node or relationship to index
* @param field field to index
* @param value value to index
@@ -116,10 +160,15 @@ public interface Neo4jOperations {
*/
<T extends PropertyContainer> Result<T> lookup(String indexName, Object query);
/**
* The query is executed on the index for this entity type returning the IndexHits wrapped in a QueryResult to be converted
* into Paths or Entities.
*/
<T extends PropertyContainer> Result<T> lookup(Class<?> indexedType, Object query);
Object query(String statement, Map<String, Object> params, TypeInformation<?> typeInformation);
/**
* Provides a cypher or gremlin query engine set up with a default entity converter.
*/
QueryEngine queryEngineFor(QueryType type);
/**
@@ -130,7 +179,7 @@ public interface Neo4jOperations {
/**
* Executes the given Gremlin statement and returns the result packaged as QueryResult as Neo4j types, not
* Gremlin types. Table rows are converted to Map<String,Object>.
* Gremlin types. The Neo4j-Graph is provided as variable "g". Table rows are converted to Map<String,Object>.
*/
Result<Object> execute(String statement, Map<String, Object> params);
@@ -141,27 +190,58 @@ public interface Neo4jOperations {
*/
Result<Path> traverse(Node startNode, TraversalDescription traversal);
/**
* Traverses the graph starting at the given node entity with the provided traversal description. The Path's of the
* traversal will be packaged into a QueryResult which can be easily converted into Nodes, Relationships or
* Graph-Entities.
*/
Result<Path> traverse(Object start, TraversalDescription traversal);
<T> Iterable<T> traverse(Object entity, Class<?> targetType, TraversalDescription traversalDescription);
/**
* Converts the Iterable into a QueryResult object for uniform handling. E.g.
* template.convert(node.getRelationships());
*/
<T> Result<T> convert(Iterable<T> iterable);
/**
* Converts a single object according to the configured ResultConverter of the Neo4j-Template.
*/
<T> T convert(Object value, Class<T> type);
/**
* Provides all instances of a given entity type using the typerepresentation strategy configured for this template.
* This method is also provided by the appropriate repository.
*/
<T> ClosableIterable<T> findAll(Class<T> entityClass);
/**
* Provies the instance count a given entity type using the typerepresentation strategy configured for this template.
* This method is also provided by the appropriate repository.
*/
<T> long count(Class<T> entityClass);
/**
* Projects a node or relationship entity to a different type. This can be used to use the same, schema free data
* in different contexts.
*/
<S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType);
/**
* Stores the given entity in the graph, if the entity is already attached to the graph, the node is updated, otherwise
* a new node is created. Attached relationships will be cascaded.
* This method is also provided by the appropriate repository.
*/
<T> T save(T entity);
/**
* Removes the given node or relationship entity or node or relationship from the graph, the entity is first removed
* from all indexes and then deleted.
*/
void remove(Object entity);
/**
* Returns the node or relationship that backs the given entity.
*/
<S extends PropertyContainer> S getPersistentState(Object entity);
}