Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Anders Nawroth
2011-10-18 02:26:47 +02:00
33 changed files with 681 additions and 328 deletions

View File

@@ -210,7 +210,7 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
}
public void NodeBacked.removeRelationshipTo(NodeBacked target, String relationshipType) {
template().removeRelationshipBetween(this, target, relationshipType);
template().deleteRelationshipBetween(this, target, relationshipType);
}
public <R extends RelationshipBacked> R NodeBacked.getRelationshipTo( NodeBacked target, Class<R> relationshipClass, String type) {

View File

@@ -102,7 +102,7 @@ public class NodeEntityTest extends EntityTestBase {
Person spouse = persistedPerson("Tina", 36);
p.setSpouse(spouse);
long id = spouse.getId();
neo4jTemplate.remove(spouse);
neo4jTemplate.delete(spouse);
tx.success();
tx.finish();
Assert.assertNull("spouse removed " + p.getSpouse(), p.getSpouse());

View File

@@ -80,7 +80,7 @@ public class SubReferenceNodeTypeRepresentationStrategyTest extends EntityTestBa
}
@Test(expected = IllegalArgumentException.class)
public void gettingTypeFromNonTypeNodeShouldThrowAnDescriptiveException() throws Exception {
Node referenceNode = neo4jTemplate.getReferenceNode(Node.class);
Node referenceNode = neo4jTemplate.getReferenceNode();
nodeTypeRepresentationStrategy.getJavaType(referenceNode);
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.data.neo4j.aspects.fieldaccess;
package org.springframework.data.neo4j.cross_store.fieldaccess;
import org.springframework.data.neo4j.fieldaccess.FieldAccessListener;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorListenerFactory;

View File

@@ -24,7 +24,7 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.aspects.core.NodeBacked;
import org.springframework.data.neo4j.aspects.fieldaccess.JpaIdFieldAccessListenerFactory;
import org.springframework.data.neo4j.cross_store.fieldaccess.JpaIdFieldAccessListenerFactory;
import org.springframework.data.neo4j.fieldaccess.*;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;

View File

@@ -1,91 +1,91 @@
package org.neo4j.examples.imdb.domain;
import org.neo4j.graphalgo.GraphAlgoFactory;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.kernel.StandardExpander;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
class ImdbServiceImpl implements ImdbService {
@Autowired
private Neo4jTemplate template;
@Autowired
private ImdbSearchEngine searchEngine;
@Autowired
private MovieRepository movieRepository;
@Autowired
private ActorRepository actorRepository;
public Actor createActor(final String name) {
final Actor actor = new Actor().persist();
actor.setName(name);
searchEngine.indexActor(actor);
return actor;
}
public Movie createMovie(final String title, final int year) {
final Movie movie = new Movie().persist();
movie.setTitle(title);
movie.setYear(year);
searchEngine.indexMovie(movie);
return movie;
}
public Actor getActor(final String name) {
Actor actor = actorRepository.findByPropertyValue("name", name);
if (actor != null) return actor;
return searchEngine.searchActor(name);
}
public Movie getMovie(final String title) {
Movie movie = getExactMovie(title);
if (movie != null) return movie;
return searchEngine.searchMovie(title);
}
public Movie getExactMovie(final String title) {
return movieRepository.findByPropertyValue("title", title);
}
@Transactional
public void setupReferenceRelationship() {
Node referenceNode = template.getReferenceNode(Node.class);
Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin");
if (bacon == null) throw new NoSuchElementException("Unable to find Kevin Bacon actor");
referenceNode.createRelationshipTo(bacon.getPersistentState(), RelTypes.IMDB);
}
public List<?> getBaconPath(final Actor actor) {
if (actor == null) throw new IllegalArgumentException("Null actor");
Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin");
Path path = GraphAlgoFactory.shortestPath(StandardExpander.DEFAULT.add(RelTypes.ACTS_IN), 10).findSinglePath(bacon.getPersistentState(), actor.getPersistentState());
if (path==null) return Collections.emptyList();
return convertNodesToActorsAndMovies(path);
}
private List<?> convertNodesToActorsAndMovies(final Path list) {
final List<Object> actorAndMovieList = new LinkedList<Object>();
int mod = 0;
for (Node node : list.nodes()) {
if (mod++ % 2 == 0) {
actorAndMovieList.add(template.createEntityFromState(node, Actor.class));
} else {
actorAndMovieList.add(template.createEntityFromState(node, Movie.class));
}
}
return actorAndMovieList;
}
package org.neo4j.examples.imdb.domain;
import org.neo4j.graphalgo.GraphAlgoFactory;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.kernel.StandardExpander;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
class ImdbServiceImpl implements ImdbService {
@Autowired
private Neo4jTemplate template;
@Autowired
private ImdbSearchEngine searchEngine;
@Autowired
private MovieRepository movieRepository;
@Autowired
private ActorRepository actorRepository;
public Actor createActor(final String name) {
final Actor actor = new Actor().persist();
actor.setName(name);
searchEngine.indexActor(actor);
return actor;
}
public Movie createMovie(final String title, final int year) {
final Movie movie = new Movie().persist();
movie.setTitle(title);
movie.setYear(year);
searchEngine.indexMovie(movie);
return movie;
}
public Actor getActor(final String name) {
Actor actor = actorRepository.findByPropertyValue("name", name);
if (actor != null) return actor;
return searchEngine.searchActor(name);
}
public Movie getMovie(final String title) {
Movie movie = getExactMovie(title);
if (movie != null) return movie;
return searchEngine.searchMovie(title);
}
public Movie getExactMovie(final String title) {
return movieRepository.findByPropertyValue("title", title);
}
@Transactional
public void setupReferenceRelationship() {
Node referenceNode = template.getReferenceNode();
Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin");
if (bacon == null) throw new NoSuchElementException("Unable to find Kevin Bacon actor");
referenceNode.createRelationshipTo(bacon.getPersistentState(), RelTypes.IMDB);
}
public List<?> getBaconPath(final Actor actor) {
if (actor == null) throw new IllegalArgumentException("Null actor");
Actor bacon = actorRepository.findByPropertyValue("name", "Bacon, Kevin");
Path path = GraphAlgoFactory.shortestPath(StandardExpander.DEFAULT.add(RelTypes.ACTS_IN), 10).findSinglePath(bacon.getPersistentState(), actor.getPersistentState());
if (path==null) return Collections.emptyList();
return convertNodesToActorsAndMovies(path);
}
private List<?> convertNodesToActorsAndMovies(final Path list) {
final List<Object> actorAndMovieList = new LinkedList<Object>();
int mod = 0;
for (Node node : list.nodes()) {
if (mod++ % 2 == 0) {
actorAndMovieList.add(template.createEntityFromState(node, Actor.class));
} else {
actorAndMovieList.add(template.createEntityFromState(node, Movie.class));
}
}
return actorAndMovieList;
}
}

View File

@@ -77,7 +77,7 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
}
@Override
public TraversalDescription createTraversalDescription() {
public TraversalDescription traversalDescription() {
return super.getRestAPI().createTraversalDescription();
}
@@ -144,8 +144,7 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
@Override
public void setResultConverter(ResultConverter resultConverter) {
this.resultConverter = resultConverter;
}
private void removeFromIndexes(Node node) {

View File

@@ -20,17 +20,21 @@ import org.junit.Assert;
import org.junit.Test;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.Relationship;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.neo4j.helpers.collection.MapUtil.map;
public class RestEntityTest extends RestTestBase {
@Test
public void testSetProperty() {
restGraphDatabase.getReferenceNode().setProperty( "name", "test" );
Node node = restGraphDatabase.getReferenceNode();
Assert.assertEquals( "test", node.getProperty( "name" ) );
assertEquals("test", node.getProperty("name"));
}
@Test
@@ -51,9 +55,30 @@ public class RestEntityTest extends RestTestBase {
public void testRemoveProperty() {
Node node = restGraphDatabase.getReferenceNode();
node.setProperty( "name", "test" );
Assert.assertEquals( "test", node.getProperty( "name" ) );
assertEquals("test", node.getProperty("name"));
node.removeProperty( "name" );
Assert.assertEquals( false, node.hasProperty( "name" ) );
assertEquals(false, node.hasProperty("name"));
}
@Test(expected = NotFoundException.class)
public void testRemoveNode() {
Node node = restGraphDatabase.createNode();
node.setProperty( "name", "test" );
final long nodeId = node.getId();
assertEquals("test", node.getProperty("name"));
restGraphDatabase.remove(node);
assertEquals(null, restGraphDatabase.getNodeById(nodeId));
}
@Test(expected = NotFoundException.class)
public void testRemoveRelationship() {
Node refNode = restGraphDatabase.getReferenceNode();
Node node = restGraphDatabase.createNode();
Relationship rel = restGraphDatabase.createRelationship(refNode, node, Type.TEST, map("name","test"));
final long relId = rel.getId();
assertEquals("test", rel.getProperty("name"));
restGraphDatabase.remove(rel);
assertEquals(null, restGraphDatabase.getRelationshipById(relId));
}
@@ -63,9 +88,9 @@ public class RestEntityTest extends RestTestBase {
Node node = restGraphDatabase.createNode();
Relationship rel = refNode.createRelationshipTo( node, Type.TEST );
rel.setProperty( "name", "test" );
Assert.assertEquals( "test", rel.getProperty( "name" ) );
assertEquals("test", rel.getProperty("name"));
Relationship foundRelationship = IsRelationshipToNodeMatcher.relationshipFromTo( refNode.getRelationships( Type.TEST, Direction.OUTGOING ), refNode, node );
Assert.assertEquals( "test", foundRelationship.getProperty( "name" ) );
assertEquals("test", foundRelationship.getProperty("name"));
}
@Test
@@ -74,13 +99,13 @@ public class RestEntityTest extends RestTestBase {
Node node = restGraphDatabase.createNode();
Relationship rel = refNode.createRelationshipTo( node, Type.TEST );
rel.setProperty( "name", "test" );
Assert.assertEquals( "test", rel.getProperty( "name" ) );
assertEquals("test", rel.getProperty("name"));
Relationship foundRelationship = IsRelationshipToNodeMatcher.relationshipFromTo( refNode.getRelationships( Type.TEST, Direction.OUTGOING ), refNode, node );
Assert.assertEquals( "test", foundRelationship.getProperty( "name" ) );
assertEquals("test", foundRelationship.getProperty("name"));
rel.removeProperty( "name" );
Assert.assertEquals( false, rel.hasProperty( "name" ) );
assertEquals(false, rel.hasProperty("name"));
Relationship foundRelationship2 = IsRelationshipToNodeMatcher.relationshipFromTo( refNode.getRelationships( Type.TEST, Direction.OUTGOING ), refNode, node );
Assert.assertEquals( false, foundRelationship2.hasProperty( "name" ) );
assertEquals(false, foundRelationship2.hasProperty("name"));
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.data.neo4j.config;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationListener;
@@ -83,6 +82,6 @@ public class ConfigurationCheck implements ApplicationListener<ContextStartedEve
}
private void updateStartTime() {
template.getReferenceNode(Node.class).setProperty("startTime", System.currentTimeMillis());
template.getReferenceNode().setProperty("startTime", System.currentTimeMillis());
}
}

View File

@@ -43,16 +43,6 @@ public interface GraphDatabase {
*/
Node getNodeById(long id);
/**
* Transactionally creates the node, sets the properties (if any).
* Two shortcut means of providing the properties (very short with static imports)
* <code>graphDatabase.createNode(PropertyMap._("name","value"));</code>
* <code>graphDatabase.createNode(PropertyMap.props().set("name","value").set("prop","anotherValue").toMap(), "name", "prop");</code>
*
*
* @param props properties to be set at node creation might be null
* @return the newly created node
*/
Node createNode(Map<String, Object> props);
/**
@@ -62,20 +52,6 @@ public interface GraphDatabase {
*/
Relationship getRelationshipById(long id);
/**
* Transactionally creates the relationship, sets the properties (if any) and indexes the given fielss (if any)
* Two shortcut means of providing the properties (very short with static imports)
* <code>graphDatabase.createRelationship(from,to,TYPE, PropertyMap._("name","value"));</code>
* <code>graphDatabase.createRelationship(from,to,TYPE, PropertyMap.props().set("name","value").set("prop","anotherValue").toMap(), "name", "prop");</code>
*
*
*
* @param startNode start-node of relationship
* @param endNode end-node of relationship
* @param type relationship type, might by an enum implementing RelationshipType or a DynamicRelationshipType.withName("name")
* @param props optional initial properties
* @return the newly created relationship
*/
Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Map<String, Object> props);
/**
@@ -98,7 +74,7 @@ public interface GraphDatabase {
/**
* @return a TraversalDescription as starting point for defining a traversal
*/
TraversalDescription createTraversalDescription();
TraversalDescription traversalDescription();
<T> QueryEngine<T> queryEngineFor(QueryType type);

View File

@@ -23,7 +23,7 @@ import org.neo4j.graphdb.PropertyContainer;
*/
public interface EntityPersister {
<S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType);
<T> T projectTo(Object entity, Class<T> targetType);
<S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type);
<S extends PropertyContainer, T> T createEntityFromStoredType(S state);
boolean isNodeEntity(Class<?> targetType);

View File

@@ -164,8 +164,8 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert
return state instanceof Node;
}
public <S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType) {
S state = getPersistentState(entity);
public <T> T projectTo(Object entity, Class<T> targetType) {
PropertyContainer state = getPersistentState(entity);
return createEntityFromState(state, targetType);
}

View File

@@ -56,6 +56,12 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
managed = ManagedEntity.class.isAssignableFrom(information.getType());
}
@Override
public void verify() {
super.verify();
if (!isManaged() && getIdProperty()==null) throw new MappingException("No id property in "+this);
}
public boolean useShortNames() {
final NodeEntity graphEntity = getAnnotation(NodeEntity.class);
if (graphEntity != null) return graphEntity.useShortNames();
@@ -156,4 +162,9 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
public Neo4jPersistentProperty getTypeProperty() {
return relationshipType;
}
@Override
public String toString() {
return String.format("%s %smanaged @%sEntity Annotations: %s",getType(),isManaged() ? "" : "un", isNodeEntity() ? "Node":"Relationship",annotations.keySet());
}
}

View File

@@ -18,10 +18,11 @@ package org.springframework.data.neo4j.repository;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.ArrayList;
import java.util.List;
public class RelationshipGraphRepository<T> extends AbstractGraphRepository<Relationship, T> implements GraphRepository<T> {
public RelationshipGraphRepository(final Class<T> clazz, final Neo4jTemplate template) {
@@ -40,13 +41,17 @@ public class RelationshipGraphRepository<T> extends AbstractGraphRepository<Rela
@Override
public T save(T entity) {
return entity;
return template.save(entity);
}
@SuppressWarnings("unchecked")
@Override
public Iterable<T> save(Iterable<? extends T> entities) {
return (Iterable<T>) entities;
List<T> result=new ArrayList<T>();
for (T entity : entities) {
result.add(template.save(entity));
}
return result;
}
}

View File

@@ -165,7 +165,7 @@ public class DelegatingGraphDatabase implements GraphDatabase {
}
@Override
public TraversalDescription createTraversalDescription() {
public TraversalDescription traversalDescription() {
return Traversal.description();
}

View File

@@ -122,8 +122,8 @@ public class EntityStateHandler {
@SuppressWarnings("unchecked")
private <S extends PropertyContainer> S createRelationship(Object entity, Neo4jPersistentEntityImpl<?> persistentEntity) {
final RelationshipProperties relationshipProperties = persistentEntity.getRelationshipProperties();
Node startNode = (Node) relationshipProperties.getStartNodeProperty().getValue(entity);
Node endNode = (Node) relationshipProperties.getStartNodeProperty().getValue(entity);
Node startNode = (Node) getPersistentState(relationshipProperties.getStartNodeProperty().getValue(entity));
Node endNode = (Node) getPersistentState(relationshipProperties.getEndeNodeProperty().getValue(entity));
Object relType = relationshipProperties.getTypeProperty().getValue(entity);
if (relType instanceof RelationshipType) {
return (S) startNode.createRelationshipTo(endNode, (RelationshipType) relType);
@@ -207,9 +207,4 @@ public class EntityStateHandler {
}
public Node getNodeState(Object entity) {
final PropertyContainer result = getPersistentState(entity);
if (result==null || result instanceof Node) return (Node) result;
throw new IllegalArgumentException("State of "+entity+" is no Node but "+result);
}
}

View File

@@ -48,8 +48,6 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import static org.springframework.data.neo4j.support.ParameterCheck.notNull;
@@ -135,6 +133,21 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
public <T> T findOne(long id, final Class<T> entityClass) {
if (isNodeEntity(entityClass)) {
final Node node = getNode(id);
if (node==null) return null;
return infrastructure.getTypeRepresentationStrategies().projectEntity(node, entityClass);
}
if (isRelationshipEntity(entityClass)) {
final Relationship relationship = getRelationship(id);
if (relationship==null) return null;
return infrastructure.getTypeRepresentationStrategies().projectEntity(relationship, entityClass);
}
throw new IllegalArgumentException("provided entity type is not annotated with @NodeEntiy nor @RelationshipEntity");
}
@Override
public <T> ClosableIterable<T> findAll(final Class<T> entityClass) {
notNull(entityClass,"entity type");
@@ -158,7 +171,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
public <S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType) {
public <T> T projectTo(Object entity, Class<T> targetType) {
notNull(entity,"entity",targetType,"new entity class");
return infrastructure.getEntityPersister().projectTo(entity, targetType);
}
@@ -183,7 +196,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
public void remove(Object entity) {
public void delete(Object entity) {
notNull(entity,"entity");
infrastructure.getEntityRemover().remove(entity);
}
@@ -218,25 +231,6 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
return convert(node, target);
}
@Override
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>... allProperties) {
final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy = isNodeEntity(target) ? infrastructure.getTypeRepresentationStrategies().getNodeTypeRepresentationStrategy() : null;
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);
}
private <T> Node createNode(Map<String, Object> properties, Class<T> target, TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy) {
final Node node = createNode(properties);
if (nodeTypeRepresentationStrategy != null) {
@@ -304,7 +298,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
return infrastructure.getEntityStateHandler().getRelationshipBetween(start,end,relationshipType);
}
@Override
public void removeRelationshipBetween(Object start, Object end, String type) {
public void deleteRelationshipBetween(Object start, Object end, String type) {
notNull(start,"start",end,"end",type,"relationshipType");
infrastructure.getEntityRemover().removeRelationshipBetween(start, end, type);
}
@@ -321,12 +315,12 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
@Override
public Relationship createRelationshipBetween(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Map<String, Object> properties) {
public Relationship createRelationshipBetween(final Node startNode, final Node endNode, final String relationshipType, final Map<String, Object> properties) {
notNull(startNode, "startNode", endNode, "endNode", relationshipType, "relationshipType", properties, "properties");
return exec(new GraphCallback<Relationship>() {
@Override
public Relationship doWithGraph(GraphDatabase graph) throws Exception {
return graph.createRelationship(startNode, endNode, relationshipType, properties);
return graph.createRelationship(startNode, endNode, DynamicRelationshipType.withName(relationshipType), properties);
}
});
}
@@ -364,11 +358,9 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
@Override
@SuppressWarnings("unchecked")
public <T> T getReferenceNode(Class<T> target) {
public Node getReferenceNode() {
try {
final Node node = infrastructure.getGraphDatabase().getReferenceNode();
if (Node.class.isAssignableFrom(target)) return (T) node;
return convert(node, target);
return infrastructure.getGraphDatabase().getReferenceNode();
} catch (RuntimeException e) {
throw translateExceptionIfPossible(e);
}
@@ -499,6 +491,11 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
}
}
@Override
public TraversalDescription traversalDescription() {
return infrastructure.getGraphDatabase().traversalDescription();
}
public EntityStateHandler getEntityStateHandler() {
return infrastructure.getEntityStateHandler();
}
@@ -522,4 +519,9 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
public MappingInfrastructure getInfrastructure() {
return infrastructure;
}
@Override
public GraphDatabase getGraphDatabase() {
return infrastructure.getGraphDatabase();
}
}

View File

@@ -22,6 +22,7 @@ import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.helpers.collection.ClosableIterable;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.conversion.Result;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.support.query.QueryEngine;
@@ -48,7 +49,10 @@ public interface Neo4jOperations {
<T> GraphRepository<T> repositoryFor(Class<T> clazz);
<T> T getReferenceNode(Class<T> target);
/**
* Returns the reference node.
*/
Node getReferenceNode();
/**
* Delegates to the GraphDatabase
@@ -74,20 +78,6 @@ public interface Neo4jOperations {
*/
<T> T createNodeAs(Class<T> target, Map<String, Object> properties);
/**
* 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);
/**
* 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);
/**
* Delegates to the GraphDatabase
@@ -101,7 +91,7 @@ public interface Neo4jOperations {
/**
* Creates a relationship with the given initial properties.
*/
Relationship createRelationshipBetween(Node startNode, Node endNode, RelationshipType type, Map<String, Object> props);
Relationship createRelationshipBetween(Node startNode, Node endNode, String type, Map<String, Object> props);
/**
* Retrieves a single relationship entity between two node entities with the given relationship type projected to the provided
@@ -117,7 +107,7 @@ public interface Neo4jOperations {
/**
* Removes the relationship of this type between the two node entities
*/
void removeRelationshipBetween(Object start, Object end, String type);
void deleteRelationshipBetween(Object start, Object end, String type);
/**
* Creates a single relationship entity between two node entities with the given relationship type projected to the provided
@@ -149,19 +139,19 @@ public interface Neo4jOperations {
<T extends PropertyContainer> T index(String indexName, T element, String field, Object value);
/**
* The value is looked up in the Neo4j index returning the IndexHits wrapped in a QueryResult to be converted
* The value is looked up in the Neo4j index returning the IndexHits wrapped in a Result to be converted
* into Paths or Entities.
*/
<T extends PropertyContainer> Result<T> lookup(String indexName, String field, Object value);
/**
* The query is executed on the index returning the IndexHits wrapped in a QueryResult to be converted
* The query is executed on the index returning the IndexHits wrapped in a Result to be converted
* into Paths or Entities.
*/
<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
* The query is executed on the index for this entity type returning the IndexHits wrapped in a Result to be converted
* into Paths or Entities.
*/
<T extends PropertyContainer> Result<T> lookup(Class<?> indexedType, Object query);
@@ -172,33 +162,33 @@ public interface Neo4jOperations {
QueryEngine queryEngineFor(QueryType type);
/**
* Runs the given cypher statement and packages the result in a QueryResult, simple conversions via the
* Runs the given cypher statement and packages the result in a Result, simple conversions via the
* registered converter-factories are already executed via this method.
*/
Result<Map<String, Object>> query(String statement, Map<String, Object> params);
/**
* Executes the given Gremlin statement and returns the result packaged as QueryResult as Neo4j types, not
* Executes the given Gremlin statement and returns the result packaged as Result as Neo4j types, not
* 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);
/**
* Traverses the graph starting at the given node 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
* traversal will be packaged into a Result which can be easily converted into Nodes, Relationships or
* Graph-Entities.
*/
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
* traversal will be packaged into a Result which can be easily converted into Nodes, Relationships or
* Graph-Entities.
*/
Result<Path> traverse(Object start, TraversalDescription traversal);
/**
* Converts the Iterable into a QueryResult object for uniform handling. E.g.
* Converts the Iterable into a Result object for uniform handling. E.g.
* template.convert(node.getRelationships());
*/
<T> Result<T> convert(Iterable<T> iterable);
@@ -208,6 +198,11 @@ public interface Neo4jOperations {
*/
<T> T convert(Object value, Class<T> type);
/**
* Retrieves a node or relationship and returns it mapped to the appropriate type
* @return mapped entity or null
*/
<T> T findOne(long id, 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.
@@ -224,7 +219,7 @@ public interface Neo4jOperations {
* 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);
<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
@@ -237,11 +232,14 @@ public interface Neo4jOperations {
* 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);
void delete(Object entity);
/**
* Returns the node or relationship that backs the given entity.
*/
<S extends PropertyContainer> S getPersistentState(Object entity);
TraversalDescription traversalDescription();
GraphDatabase getGraphDatabase();
}

View File

@@ -1,43 +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.template;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class PropertyMap {
private final Map<String, Object> properties = new HashMap<String, Object>();
public PropertyMap set(String name, Object value) {
properties.put(name, value);
return this;
}
public static PropertyMap props() {
return new PropertyMap();
}
public Map<String, Object> toMap() {
return properties;
}
public static Map<String, Object> _(String name, Object value) {
return Collections.singletonMap(name,value);
}
}

View File

@@ -1,47 +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.template.util;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Converter
{
private final Map<String, Method> valueOfs = new HashMap<String, Method>();
public Object convert(final String typeName, final String value)
{
if (value == null) return null;
if (typeName == null)
throw new IllegalArgumentException("TypeName must not be null");
try
{
Method valueOf = valueOfs.get(typeName);
if (valueOf == null)
{
final Class type = Class.forName(typeName.contains(".") ? typeName : "java.lang." + typeName);
valueOf = type.getMethod("valueOf", String.class);
valueOfs.put(typeName, valueOf);
}
return valueOf.invoke(null, value);
} catch (Exception e)
{
throw new RuntimeException(String.format("Error converting value %s from String to type %s", value, typeName), e);
}
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.data.neo4j.model;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
/**
@@ -24,6 +25,8 @@ import org.springframework.data.neo4j.annotation.NodeEntity;
*/
@NodeEntity
public class Named {
@GraphId
Long id;
public String name;
public String getName() {

View File

@@ -14,10 +14,9 @@
* limitations under the License.
*/
package org.springframework.data.neo4j.template.util;
package org.springframework.data.neo4j.repository;
import org.neo4j.graphdb.Node;
import org.springframework.data.neo4j.model.Friendship;
public interface NodeEvaluator {
boolean accept(final Node node);
public interface FriendshipRepository extends GraphRepository<Friendship> {
}

View File

@@ -66,6 +66,8 @@ public class GraphRepositoryTest {
@Autowired
GroupRepository groupRepository;
@Autowired FriendshipRepository friendshipRepository;
private TestTeam testTeam;
@BeforeTransaction
@@ -75,7 +77,7 @@ public class GraphRepositoryTest {
@Before
public void setUp() throws Exception {
testTeam = new TestTeam();
testTeam.createSDGTeam(personRepository, groupRepository);
testTeam.createSDGTeam(personRepository, groupRepository,friendshipRepository);
}
@Test

View File

@@ -16,14 +16,12 @@
package org.springframework.data.neo4j.repository;
import org.neo4j.helpers.collection.MapUtil;
import org.springframework.data.neo4j.model.*;
import java.util.Arrays;
import java.util.Map;
import org.neo4j.helpers.collection.MapUtil;
import org.springframework.data.neo4j.model.Group;
import org.springframework.data.neo4j.model.Person;
import org.springframework.data.neo4j.model.Personality;
/**
* @author mh
* @since 13.06.11
@@ -33,11 +31,12 @@ public class TestTeam {
public Person emil;
public Person david;
public Group sdg;
public Friendship friendShip;
public TestTeam() {
}
public void createSDGTeam(PersonRepository repo, GroupRepository groupRepo) {
public void createSDGTeam(GraphRepository<Person> repo, GraphRepository<Group> groupRepo, GraphRepository<Friendship> friendshipRepository) {
emil = new Person("Emil", 30);
michael = new Person("Michael", 36);
@@ -46,7 +45,8 @@ public class TestTeam {
david = new Person("David", 25);
david.setBoss(emil);
friendShip = michael.knows(david);
friendShip.setYears(2);
sdg = new Group();
sdg.setName("SDG");
sdg.addPerson(michael);
@@ -54,6 +54,7 @@ public class TestTeam {
sdg.addPerson(david);
repo.save(Arrays.asList(emil, david, michael));
friendshipRepository.save(friendShip);
groupRepo.save(sdg);
}

View File

@@ -15,16 +15,19 @@
*/
package org.springframework.data.neo4j.repository.query;
import java.util.Set;
import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import java.util.Set;
@NodeEntity
class Group {
@GraphId Long id;
@Indexed
String name;

View File

@@ -16,6 +16,7 @@
package org.springframework.data.neo4j.repository.query;
import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
@@ -23,6 +24,8 @@ import org.springframework.data.neo4j.annotation.RelatedTo;
@NodeEntity
class Person {
@GraphId Long id;
@Indexed
String name;
int age;

View File

@@ -0,0 +1,314 @@
/**
* 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.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.kernel.Traversal;
import org.springframework.data.neo4j.conversion.EndResult;
import org.springframework.data.neo4j.model.Friendship;
import org.springframework.data.neo4j.model.Group;
import org.springframework.data.neo4j.model.Named;
import org.springframework.data.neo4j.model.Person;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.*;
import static org.neo4j.graphdb.Direction.OUTGOING;
import static org.neo4j.helpers.collection.IteratorUtil.asCollection;
/**
* @author mh
* @since 17.10.11
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:template-config-context.xml"})
@Transactional
public class EntityNeo4jTemplateTest extends EntityTestBase {
public static final DynamicRelationshipType KNOWS = DynamicRelationshipType.withName("knows");
@Before
public void setUp() throws Exception {
createTeam();
}
@Test
public void testRepositoryFor() throws Exception {
final GraphRepository<Person> personRepository = neo4jTemplate.repositoryFor(Person.class);
final GraphRepository<Group> groupRepository = neo4jTemplate.repositoryFor(Group.class);
final GraphRepository<Friendship> friendshipRepository = neo4jTemplate.repositoryFor(Friendship.class);
testTeam.createSDGTeam(personRepository,groupRepository,friendshipRepository);
final Person found = personRepository.findOne(testTeam.michael.getId());
assertEquals(found.getId(),testTeam.michael.getId());
}
@Test
public void testRelationshipRepositoryFor() throws Exception {
final GraphRepository<Friendship> friendshipRepository = neo4jTemplate.repositoryFor(Friendship.class);
final Friendship found = friendshipRepository.findOne(testTeam.friendShip.getId());
assertEquals(found.getId(),testTeam.friendShip.getId());
}
@Test
public void testGetIndexForType() throws Exception {
final Index<PropertyContainer> personIndex = neo4jTemplate.getIndex(Person.class);
assertEquals("Person",personIndex.getName());
}
@Test
public void testGetIndexForName() throws Exception {
final Index<PropertyContainer> nameIndex = neo4jTemplate.getIndex(Person.NAME_INDEX);
assertEquals(Person.NAME_INDEX, nameIndex.getName());
}
@Test
public void testGetIndexForNoTypeAndName() throws Exception {
final Index<PropertyContainer> nameIndex = neo4jTemplate.getIndex(null,Person.NAME_INDEX);
assertEquals(Person.NAME_INDEX,nameIndex.getName());
}
@Test
public void testGetIndexForTypeAndNoName() throws Exception {
final Index<PropertyContainer> nameIndex = neo4jTemplate.getIndex(Person.class,null);
assertEquals("Person",nameIndex.getName());
}
@Test
public void testGetIndexForTypeAndName() throws Exception {
final Index<PropertyContainer> nameIndex = neo4jTemplate.getIndex(Person.class,Person.NAME_INDEX);
assertEquals(Person.NAME_INDEX, nameIndex.getName());
}
@Test
public void testFindOne() throws Exception {
final Person found = neo4jTemplate.findOne(testTeam.michael.getId(), Person.class);
assertEquals(found.getId(),testTeam.michael.getId());
}
@Test
public void testFindAll() throws Exception {
final Collection<Person> people = asCollection(neo4jTemplate.findAll(Person.class));
assertEquals(3,people.size());
}
@Test
public void testCount() throws Exception {
assertEquals(3,neo4jTemplate.count(Person.class));
}
@Test
public void testCreateRelationshipEntityFromStoredType() throws Exception {
final Relationship friendshipRelationship = getRelationshipState(testTeam.friendShip);
Friendship found = neo4jTemplate.createEntityFromStoredType(friendshipRelationship);
assertEquals(testTeam.friendShip.getId(),found.getId());
}
@Test
public void testCreateNodeEntityFromStoredType() throws Exception {
final Node michaelNode = getNodeState(testTeam.michael);
Person found = neo4jTemplate.createEntityFromStoredType(michaelNode);
assertEquals(testTeam.michael.getId(),found.getId());
}
@Test
public void testCreateEntityFromState() throws Exception {
final PropertyContainer michaelNode = getNodeState(testTeam.michael);
Person found = neo4jTemplate.createEntityFromStoredType(michaelNode);
assertEquals(testTeam.michael.getId(),found.getId());
}
@Test
public void testProjectTo() throws Exception {
final Named named = neo4jTemplate.projectTo(testTeam.sdg, Named.class);
assertEquals(testTeam.sdg.getName(),named.getName());
}
@Test
public void testGetPersistentState() throws Exception {
assertEquals(testTeam.michael.getId(),(Long)((Node)neo4jTemplate.getPersistentState(testTeam.michael)).getId());
}
@Test
public void testSetPersistentState() throws Exception {
}
@Test
@Ignore("TODO execute non tx")
public void testDelete() throws Exception {
final Long id = testTeam.michael.getId();
neo4jTemplate.delete(testTeam.michael);
assertNull(neo4jTemplate.getGraphDatabase().getNodeById(id));
}
@Test
@Ignore("TODO execute non tx")
public void testRemoveNodeEntity() throws Exception {
final Long id = testTeam.michael.getId();
neo4jTemplate.removeNodeEntity(testTeam.michael);
assertNull(neo4jTemplate.getGraphDatabase().getNodeById(id));
}
@Test
@Ignore("TODO execute non tx")
public void testRemoveRelationshipEntity() throws Exception {
final Long id = testTeam.friendShip.getId();
neo4jTemplate.removeRelationshipEntity(testTeam.friendShip);
assertNull(neo4jTemplate.getGraphDatabase().getRelationshipById(id));
}
@Test
public void testCreateNodeAs() throws Exception {
}
@Test
public void testIsNodeEntity() throws Exception {
}
@Test
public void testIsRelationshipEntity() throws Exception {
}
@Test
public void testSave() throws Exception {
}
@Test
public void testIsManaged() throws Exception {
}
@Test
public void testQuery() throws Exception {
}
@Test
public void testGetRelationshipBetweenNodes() throws Exception {
final Relationship knows = neo4jTemplate.getRelationshipBetween(getNodeState(testTeam.michael), getNodeState(testTeam.david), "knows");
assertEquals(testTeam.friendShip.getId(),(Long)knows.getId());
}
@Test
public void testGetAutoPersistedRelationshipBetweenNodes() throws Exception {
final Node emilNode = getNodeState(testTeam.emil);
final Node michaelNode = getNodeState(testTeam.michael);
final Relationship boss = neo4jTemplate.getRelationshipBetween(emilNode, michaelNode, "boss");
assertNotNull("found relationship",boss);
assertEquals(michaelNode,boss.getEndNode());
assertEquals(emilNode,boss.getStartNode());
}
@Test
public void testGetRelationshipBetween() throws Exception {
final Friendship knows = neo4jTemplate.getRelationshipBetween(testTeam.michael, testTeam.david, Friendship.class, "knows");
assertEquals(testTeam.friendShip.getId(),knows.getId());
}
@Test
public void testDeleteRelationshipBetween() throws Exception {
neo4jTemplate.deleteRelationshipBetween(testTeam.michael,testTeam.david,"knows");
assertNull("relationship deleted", getNodeState(testTeam.michael).getSingleRelationship(KNOWS, OUTGOING));
}
@Test
public void testCreateRelationshipBetweenNodes() throws Exception {
final Friendship friendship = neo4jTemplate.createRelationshipBetween(testTeam.david, testTeam.emil, Friendship.class, "knows", false);
assertEquals(friendship.getId(),(Long)getNodeState(testTeam.david).getSingleRelationship(KNOWS, OUTGOING).getId());
}
@Test
public void testCreateDuplicateRelationshipBetweenNodes() throws Exception {
neo4jTemplate.createRelationshipBetween(testTeam.michael, testTeam.david, Friendship.class, "knows", true);
assertEquals(2, asCollection(getNodeState(testTeam.michael).getRelationships(KNOWS, OUTGOING)).size());
}
@Test
public void testCreateRelationshipBetween() throws Exception {
final Node davidNode = getNodeState(testTeam.david);
final Relationship friendship = neo4jTemplate.createRelationshipBetween(davidNode, getNodeState(testTeam.emil), "knows", MapUtil.map("years", 10));
assertEquals(friendship.getId(),davidNode.getSingleRelationship(KNOWS, OUTGOING).getId());
assertEquals(10,friendship.getProperty("years"));
}
@Test
public void testConvertSingle() throws Exception {
final Person p = neo4jTemplate.convert(neo4jTemplate.getPersistentState(testTeam.michael), Person.class);
assertEquals(testTeam.michael.getName(),p.getName());
}
@Test
public void testConvert() throws Exception {
final EndResult<Group> groups = neo4jTemplate.convert(Arrays.asList(getNodeState(testTeam.sdg))).to(Group.class);
assertEquals(testTeam.sdg.getName(),groups.iterator().next().getName());
}
@Test
public void testQueryEngineFor() throws Exception {
}
@Test
public void testTraverse() throws Exception {
final TraversalDescription traversalDescription = neo4jTemplate.traversalDescription().relationships(DynamicRelationshipType.withName("knows"), Direction.OUTGOING).filter(Traversal.returnAllButStartNode());
final Person knows = neo4jTemplate.traverse(testTeam.michael, traversalDescription).to(Person.class).single();
assertEquals(testTeam.david.getName(), knows.getName());
}
@Test
public void testLookup() throws Exception {
}
}

View File

@@ -0,0 +1,107 @@
/**
* 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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.neo4j.model.FriendshipRepository;
import org.springframework.data.neo4j.model.GroupRepository;
import org.springframework.data.neo4j.model.PersonRepository;
import org.springframework.data.neo4j.repository.TestTeam;
import org.springframework.data.neo4j.support.node.Neo4jHelper;
import org.springframework.test.context.transaction.BeforeTransaction;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author mh
* @since 15.10.11
*/
public class EntityTestBase {
protected final Log log = LogFactory.getLog(getClass());
@Autowired protected Neo4jTemplate neo4jTemplate;
@Autowired protected ConversionService conversionService;
@Autowired protected GraphDatabaseService graphDatabaseService;
@Autowired protected PersonRepository personRepository;
@Autowired protected GroupRepository groupRepository;
@Autowired protected FriendshipRepository friendshipRepository;
protected TestTeam testTeam = new TestTeam();
public void createTeam() throws Exception {
testTeam.createSDGTeam(personRepository, groupRepository,friendshipRepository);
}
protected Node getNodeState(Object entity) {
return neo4jTemplate.getPersistentState(entity);
}
protected Long getNodeId(Object entity) {
final Node node = neo4jTemplate.getPersistentState(entity);
return node == null ? null : node.getId();
}
protected Long getRelationshipId(Object entity) {
final Relationship rel = neo4jTemplate.getPersistentState(entity);
return rel == null ? null : rel.getId();
}
protected boolean hasPersistentState(Object entity) {
return neo4jTemplate.getPersistentState(entity)!=null;
}
protected Relationship getRelationshipState(Object entity) {
return neo4jTemplate.getPersistentState(entity);
}
@SuppressWarnings("unchecked")
public <T> T persist(T entity) {
return (T) neo4jTemplate.save(entity);
}
protected <T> Set<T> set(T... values) {
return new HashSet<T>(Arrays.<T>asList(values));
}
protected void manualCleanDb() {
Transaction tx = graphDatabaseService.beginTx();
try {
cleanDb();
tx.success();
} finally {
tx.finish();
}
}
@Before
public void cleanDbBeforeTest() {
Neo4jHelper.cleanDb(neo4jTemplate);
}
@BeforeTransaction
public void cleanDb() {
Neo4jHelper.cleanDb(neo4jTemplate);
}
}

View File

@@ -51,7 +51,7 @@ import static org.neo4j.helpers.collection.MapUtil.map;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:template-config-context.xml"})
public class GraphDatabaseContextTemplateTest {
public class FullNeo4jTemplateTest {
private static final DynamicRelationshipType KNOWS = DynamicRelationshipType.withName("knows");
private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has");
@Autowired
@@ -190,7 +190,7 @@ public class GraphDatabaseContextTemplateTest {
@Test
public void testGetReferenceNode() throws Exception {
assertEquals(referenceNode, neo4jTemplate.getReferenceNode(Node.class));
assertEquals(referenceNode, neo4jTemplate.getReferenceNode());
}
@Test
@@ -316,7 +316,7 @@ public class GraphDatabaseContextTemplateTest {
@Test
public void shouldCreateRelationshipWithProperty() throws Exception {
Relationship relationship = neo4jTemplate.createRelationshipBetween(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());

View File

@@ -202,7 +202,7 @@ public class Neo4jTemplateApiTest {
@Test
public void testGetReferenceNode() throws Exception {
assertEquals(referenceNode,template.getReferenceNode(Node.class));
assertEquals(referenceNode,template.getReferenceNode());
}
@Test
@@ -318,7 +318,7 @@ public class Neo4jTemplateApiTest {
@Test
public void shouldCreateRelationshipWithProperty() throws Exception {
Relationship relationship = template.createRelationshipBetween(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());

View File

@@ -52,13 +52,14 @@ public class NeoTraversalTest extends NeoApiTest {
final Set<String> resultSet = new HashSet<String>();
@SuppressWarnings("deprecation") final TraversalDescription description = Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2));
final Result<Path> queryResult = template.traverse(template.getReferenceNode(Node.class), description);
queryResult.handle(new Handler<Path>() {
final Result<Path> result = template.traverse(template.getReferenceNode(), description);
result.handle(new Handler<Path>() {
@Override
public void handle(Path value) {
final String name = (String) value.endNode().getProperty("name", "");
resultSet.add(name);
}});
}
});
assertEquals("all members", new HashSet<String>(asList("grandpa", "grandma", "daughter", "son", "man", "wife", "family")), resultSet);
}

View File

@@ -61,7 +61,7 @@ public class SnippetNeo4jTemplateMethodsTest extends DocumentingTestBase {
Node mark = neo.createNode(map("name", "Mark"));
Node thomas = neo.createNode(map("name", "Thomas"));
neo.createRelationshipBetween(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

View File

@@ -9,15 +9,15 @@
<xi:include href="../snippets/SnippetNeo4jTemplateMethods.xml"/>
<section>
<title>QueryResult</title>
<title>Result</title>
<para>
All querying methods of the template return a uniform result type: <code>QueryResult&lt;T&gt;</code>
All querying methods of the template return a uniform result type: <code>Result&lt;T&gt;</code>
which is also an <code>Iterable&lt;T&gt;</code>. The query result offers methods of converting each
element to a target type <code>queryResult.to(Type.class)</code> optionally supplying a
element to a target type <code>result.to(Type.class)</code> optionally supplying a
<code>ResultConverter&lt;FROM,TO&gt;</code> which takes care of custom conversions. By default most
query methods can already handle conversions from and to: Paths, Nodes, Relationship and GraphEntities
as well as conversions backed by registered ConversionServices. A converted <code>QueryResult&lt;FROM&gt;</code> is an
<code>Iterable&lt;TO&gt;</code>. QueryResults can be limited to a single value using the <code>queryResult.single()</code>
as well as conversions backed by registered ConversionServices. A converted <code>Result&lt;FROM&gt;</code> is an
<code>Iterable&lt;TO&gt;</code>. Results can be limited to a single value using the <code>result.single()</code>
method. It also offers support for a pure callback function using a <code>Handler&lt;T&gt;</code>.
</para>
</section>
@@ -29,7 +29,7 @@
<para>
The <code>lookup()</code> methods either take a field/value combination to look for exact matches in the
index, or a Lucene query object or string to handle more complex queries. All <code>lookup()</code>
methods return a <code>QueryResult&lt;PropertyContainer&gt;</code> to be used or transformed.
methods return a <code>Result&lt;PropertyContainer&gt;</code> to be used or transformed.
</para>
</section>
<section>
@@ -38,7 +38,7 @@
The traversal methods are at the core of graph operations.
The <code>traverse()</code> method covers the full traversal operation that takes a
<code>TraversalDescription</code> (typically built with the <code>Traversal.description()</code>
DSL) and runs it from the given start node. <code>traverse</code> returns a <code>QueryResult&lt;Path&gt;</code>
DSL) and runs it from the given start node. <code>traverse</code> returns a <code>Result&lt;Path&gt;</code>
to be used or transformed.
</para>
</section>
@@ -47,7 +47,7 @@
<para>
The <code>Neo4jTemplate</code> also allows execution of arbitrary Cypher queries. Via the <code>query</code>
methods the statement and parameter-Map are provided. Cypher Queries return tabular results, so the
<code>QueryResult&lt;Map&lt;String,Object&gt;&gt;</code> contains the rows which can be either used as they are
<code>Result&lt;Map&lt;String,Object&gt;&gt;</code> contains the rows which can be either used as they are
or converted as needed.
</para>
</section>
@@ -56,7 +56,7 @@
<para>
Gremlin Scripts can run with the <code>execute</code> method, which also takes the parameters that will be
available as variables inside the script. The result of the executions is a generic
<code>QueryResult&lt;Object&gt;</code> fit for conversion or usage.
<code>Result&lt;Object&gt;</code> fit for conversion or usage.
</para>
</section>
<section>