david: extended tests, added relationship info
This commit is contained in:
@@ -2,6 +2,7 @@ package org.springframework.persistence.graph.neo4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.reflect.FieldSignature;
|
||||
import org.neo4j.graphdb.Direction;
|
||||
@@ -118,7 +119,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
if (me == null) {
|
||||
throw new IllegalStateException("Entity must have a backing Node");
|
||||
}
|
||||
org.neo4j.graphdb.Relationship singleRelationship = getRelationship(me, fieldSignature);
|
||||
org.neo4j.graphdb.Relationship singleRelationship = getRelationship(me, new RelationshipInfo(fieldSignature));
|
||||
|
||||
// TODO is this correct
|
||||
// [mh] i assume only for null
|
||||
@@ -137,15 +138,8 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
}
|
||||
|
||||
|
||||
private org.neo4j.graphdb.Relationship getRelationship(Node me, FieldSignature f) {
|
||||
Relationship r = f.getField().getAnnotation(Relationship.class);
|
||||
if (r == null) {
|
||||
RelationshipType type=DynamicRelationshipType.withName(getNeo4jPropertyName((Signature)f));
|
||||
return me.getSingleRelationship(type, Direction.OUTGOING);
|
||||
}
|
||||
RelationshipType type = DynamicRelationshipType.withName(r.type());
|
||||
org.neo4j.graphdb.Relationship singleRelationship = me.getSingleRelationship(type, r.direction().toNeo4jDir());
|
||||
return singleRelationship;
|
||||
private org.neo4j.graphdb.Relationship getRelationship(Node me, RelationshipInfo relInfo) {
|
||||
return me.getSingleRelationship(relInfo.getType(), relInfo.getDirection());
|
||||
}
|
||||
|
||||
|
||||
@@ -162,12 +156,8 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
|
||||
// Look for a relationship
|
||||
if (isNeo4jRelationshipField(f)) {
|
||||
Relationship r = f.getAnnotation(Relationship.class);
|
||||
if (r == null) {
|
||||
graphEntityFieldSet(entity, (NodeBacked) newVal, getNeo4jPropertyName(thisJoinPoint.getSignature()),Direction.OUTGOING);
|
||||
} else {
|
||||
graphEntityFieldSet(entity, (NodeBacked) newVal, r.type(), r.direction().toNeo4jDir());
|
||||
}
|
||||
RelationshipInfo relInfo = new RelationshipInfo(fieldSignature);
|
||||
graphEntityFieldSet(entity, (NodeBacked) newVal, relInfo.getType(), relInfo.getDirection());
|
||||
log.info("SET " + f + " -> Neo4J relationship with value=[" + newVal + "]");
|
||||
return null;
|
||||
}
|
||||
@@ -178,10 +168,16 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
}
|
||||
|
||||
// todo what happens to the previous value, remove relationships?
|
||||
private void graphEntityFieldSet(NodeBacked entity, NodeBacked newVal, String relationshipName, Direction direction) {
|
||||
RelationshipType type = DynamicRelationshipType.withName(relationshipName);
|
||||
private void graphEntityFieldSet(NodeBacked entity, NodeBacked newVal, RelationshipType relationshipType, Direction direction) {
|
||||
RelationshipType type = relationshipType;//DynamicRelationshipType.withName(relationshipTypeName);
|
||||
|
||||
Node me = entity.getUnderlyingNode();
|
||||
for ( org.neo4j.graphdb.Relationship relationship : me.getRelationships(type, direction) ) {
|
||||
relationship.delete();
|
||||
}
|
||||
if (newVal == null) {
|
||||
return;
|
||||
}
|
||||
Node targetNode = newVal.getUnderlyingNode();
|
||||
switch(direction) {
|
||||
case OUTGOING : me.createRelationshipTo(targetNode, type); break;
|
||||
@@ -198,9 +194,27 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
return NodeBacked.class.isAssignableFrom(f.getType());
|
||||
}
|
||||
|
||||
|
||||
private String getNeo4jPropertyName(Signature sig) {
|
||||
// TODO: Do something better with this.
|
||||
private static String getNeo4jPropertyName(Signature sig) {
|
||||
return sig.toShortString();
|
||||
}
|
||||
|
||||
public static class RelationshipInfo {
|
||||
private Relationship relAnnotation;
|
||||
private final FieldSignature fieldSignature;
|
||||
|
||||
public RelationshipInfo(FieldSignature fieldSignature) {
|
||||
this.fieldSignature = fieldSignature;
|
||||
relAnnotation = fieldSignature.getField().getAnnotation(Relationship.class);
|
||||
}
|
||||
|
||||
public RelationshipType getType() {
|
||||
return DynamicRelationshipType.withName((relAnnotation == null) ? getNeo4jPropertyName(fieldSignature) : relAnnotation.type());
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return (relAnnotation == null) ? Direction.OUTGOING : relAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,14 @@ public class Person {
|
||||
|
||||
Person spouse;
|
||||
|
||||
@Relationship(type="mother",direction=Direction.BOTH)
|
||||
@Relationship(type="mother", direction=Direction.OUTGOING)
|
||||
Person mother;
|
||||
|
||||
@Relationship(type="boss", direction=Direction.INCOMING)
|
||||
Person boss;
|
||||
|
||||
@Relationship(type="friend", direction=Direction.BOTH)
|
||||
Person friend;
|
||||
|
||||
public Person(String name, int age) {
|
||||
this.name = name;
|
||||
@@ -44,18 +50,31 @@ public class Person {
|
||||
return spouse;
|
||||
}
|
||||
|
||||
|
||||
public void setSpouse(Person spouse) {
|
||||
this.spouse = spouse;
|
||||
}
|
||||
|
||||
|
||||
public Person getMother() {
|
||||
return mother;
|
||||
}
|
||||
|
||||
|
||||
public void setMother(Person mother) {
|
||||
this.mother = mother;
|
||||
}
|
||||
|
||||
public Person getBoss() {
|
||||
return boss;
|
||||
}
|
||||
public void setBoss(Person boss) {
|
||||
this.boss = boss;
|
||||
}
|
||||
|
||||
public Person getFriend() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
public void setFriend(Person friend) {
|
||||
this.friend = friend;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import junit.framework.Assert;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
@@ -18,12 +19,16 @@ import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class Neo4jGraphPersistenceTest {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Autowired
|
||||
private EntityInstantiator<NodeBacked,Node> nodeInstantiator;
|
||||
|
||||
@@ -42,8 +47,7 @@ public class Neo4jGraphPersistenceTest {
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testUserConstructor() {
|
||||
int age = 39;
|
||||
Person p = new Person("Rod", age);
|
||||
Person p = new Person("Rod", 39);
|
||||
Assert.assertEquals(p.getName(), p.getUnderlyingNode().getProperty("Person.name"));
|
||||
Assert.assertEquals(p.getAge(), p.getUnderlyingNode().getProperty("Person.age"));
|
||||
insertedId = p.getId();
|
||||
@@ -51,19 +55,91 @@ public class Neo4jGraphPersistenceTest {
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateRelationshipOnSet() {
|
||||
Person p = new Person("Michael", 35);
|
||||
Person spouse=new Person("Tina",36);
|
||||
p.setSpouse(spouse);
|
||||
Assert.assertEquals("Tina", p.getSpouse().getUnderlyingNode().getProperty("Person.name"));
|
||||
Node spouseNode=p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
|
||||
Assert.assertEquals(spouse.getUnderlyingNode(), spouseNode);
|
||||
public void testSetProperties() {
|
||||
Person p = new Person("Foo", 2);
|
||||
p.setName("Michael");
|
||||
p.setAge(35);
|
||||
Assert.assertEquals("Michael", p.getUnderlyingNode().getProperty("Person.name"));
|
||||
Assert.assertEquals(35, p.getUnderlyingNode().getProperty("Person.age"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateRelationshipWithoutAnnotationOnSet() {
|
||||
log.debug("testCreateRelationshipWithoutAnnotationOnSet");
|
||||
Person p = new Person("Michael", 35);
|
||||
Person spouse = new Person("Tina",36);
|
||||
p.setSpouse(spouse);
|
||||
Node spouseNode=p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
|
||||
Assert.assertEquals(spouse.getUnderlyingNode(), spouseNode);
|
||||
Assert.assertEquals(spouse, p.getSpouse());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateRelationshipWithAnnotationOnSet() {
|
||||
log.debug("testCreateRelationshipWithAnnotationOnSet");
|
||||
Person p = new Person("Michael", 35);
|
||||
Person mother = new Person("Gabi",60);
|
||||
p.setMother(mother);
|
||||
Node motherNode = p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("mother"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
|
||||
Assert.assertEquals(mother.getUnderlyingNode(), motherNode);
|
||||
Assert.assertEquals(mother, p.getMother());
|
||||
}
|
||||
|
||||
// TODO test delete relationship
|
||||
@Test
|
||||
@Transactional
|
||||
public void testDeleteRelationship() {
|
||||
log.debug("testDeleteRelationship");
|
||||
Person p = new Person("Michael", 35);
|
||||
Person spouse = new Person("Tina", 36);
|
||||
p.setSpouse(spouse);
|
||||
p.setSpouse(null);
|
||||
Assert.assertNull(p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING));
|
||||
Assert.assertNull(p.getSpouse());
|
||||
}
|
||||
|
||||
// TODO test delete previous relationship
|
||||
@Test
|
||||
@Transactional
|
||||
public void testDeletePreviousRelationshipOnNewRelationship() {
|
||||
log.debug("testDeletePreviousRelationshipOnNewRelationship");
|
||||
Person p = new Person("Michael", 35);
|
||||
Person spouse = new Person("Tina", 36);
|
||||
Person friend = new Person("Helga", 34);
|
||||
p.setSpouse(spouse);
|
||||
p.setSpouse(friend);
|
||||
Assert.assertEquals(friend.getUnderlyingNode(), p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("Person.spouse"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode());
|
||||
Assert.assertEquals(friend, p.getSpouse());
|
||||
}
|
||||
|
||||
// TODO test incoming relationship
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateIncomingRelationshipWithAnnotationOnSet() {
|
||||
Person p = new Person("David", 25);
|
||||
Person boss = new Person("Emil", 32);
|
||||
p.setBoss(boss);
|
||||
Assert.assertEquals(boss.getUnderlyingNode(), p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("boss"), org.neo4j.graphdb.Direction.INCOMING).getStartNode());
|
||||
Assert.assertEquals(boss, p.getBoss());
|
||||
}
|
||||
|
||||
// TODO test bidirectional relationship
|
||||
@Ignore
|
||||
@Test
|
||||
@Transactional
|
||||
public void testBidirectionalRelationshipWithAnnotationOnSet() {
|
||||
Person p = new Person("Michael", 35);
|
||||
Person friend = new Person("David", 25);
|
||||
p.setFriend(friend);
|
||||
}
|
||||
|
||||
// TODO test remove property (set to null)
|
||||
@Test
|
||||
@Transactional
|
||||
public void testInstantiatedFinder() {
|
||||
log.debug("testInstantiatedFinder");
|
||||
Node n = findPersonTestNode();
|
||||
Person found = nodeInstantiator.createEntityFromState(n, Person.class);
|
||||
Assert.assertEquals("Rod", found.getUnderlyingNode().getProperty("Person.name"));
|
||||
|
||||
Reference in New Issue
Block a user