applied davids patch
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package org.springframework.persistence.graph.neo4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.reflect.FieldSignature;
|
||||
import org.neo4j.graphdb.Direction;
|
||||
@@ -118,7 +120,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, f);
|
||||
org.neo4j.graphdb.Relationship singleRelationship = getRelationship(me, RelationshipInfo.forField(f));
|
||||
|
||||
// TODO is this correct
|
||||
// [mh] i assume only for null
|
||||
@@ -137,15 +139,8 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
}
|
||||
|
||||
|
||||
private org.neo4j.graphdb.Relationship getRelationship(Node me, Field field) {
|
||||
Relationship r = field.getAnnotation(Relationship.class);
|
||||
if (r == null) {
|
||||
RelationshipType type=DynamicRelationshipType.withName(getNeo4jPropertyName(field));
|
||||
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,10 +157,9 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
|
||||
// Look for a relationship
|
||||
if (isNeo4jRelationshipField(f)) {
|
||||
RelationshipInfo relInfo = RelationshipInfo.forField(f);
|
||||
graphEntityFieldSet(entity, (NodeBacked) newVal, relInfo);
|
||||
|
||||
org.neo4j.graphdb.Relationship relationship=getRelationship(entity.getUnderlyingNode(), f);
|
||||
if (relationship!=null) relationship.delete();
|
||||
addRelationship(entity, newVal, f);
|
||||
log.info("SET " + f + " -> Neo4J relationship with value=[" + newVal + "]");
|
||||
return null;
|
||||
}
|
||||
@@ -175,29 +169,20 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addRelationship(NodeBacked entity, Object newVal, Field f) {
|
||||
Relationship r = f.getAnnotation(Relationship.class);
|
||||
if (r == null) {
|
||||
addRelationship(entity, (NodeBacked) newVal, getNeo4jPropertyName(f),Direction.OUTGOING);
|
||||
} else {
|
||||
addRelationship(entity, (NodeBacked) newVal, r.type(), r.direction().toNeo4jDir());
|
||||
}
|
||||
}
|
||||
|
||||
// todo what happens to the previous value, remove relationships?
|
||||
private void addRelationship(NodeBacked entity, NodeBacked newVal, String relationshipName, Direction direction) {
|
||||
RelationshipType type = DynamicRelationshipType.withName(relationshipName);
|
||||
|
||||
private void graphEntityFieldSet(NodeBacked entity, NodeBacked newVal, RelationshipInfo relationshipInfo) {
|
||||
Node me = entity.getUnderlyingNode();
|
||||
for ( org.neo4j.graphdb.Relationship relationship : me.getRelationships(relationshipInfo.getType(), relationshipInfo.getDirection()) ) {
|
||||
relationship.delete();
|
||||
}
|
||||
if (newVal == null) {
|
||||
return;
|
||||
}
|
||||
Node targetNode = newVal.getUnderlyingNode();
|
||||
switch(direction) {
|
||||
case OUTGOING : me.createRelationshipTo(targetNode, type); break;
|
||||
case INCOMING : targetNode.createRelationshipTo(me, type); break;
|
||||
case BOTH :
|
||||
me.createRelationshipTo(targetNode, type);
|
||||
targetNode.createRelationshipTo(me, type);
|
||||
break;
|
||||
switch(relationshipInfo.getDirection()) {
|
||||
case OUTGOING : me.createRelationshipTo(targetNode, relationshipInfo.getType()); break;
|
||||
case INCOMING : targetNode.createRelationshipTo(me, relationshipInfo.getType()); break;
|
||||
default : throw new IllegalArgumentException("invalid direction "+relationshipInfo.getDirection());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +191,31 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
return NodeBacked.class.isAssignableFrom(f.getType());
|
||||
}
|
||||
|
||||
|
||||
private String getNeo4jPropertyName(Field field) {
|
||||
private static String getNeo4jPropertyName(Field field) {
|
||||
return String.format("%s.%s",field.getDeclaringClass().getSimpleName(),field.getName());
|
||||
}
|
||||
|
||||
public static class RelationshipInfo {
|
||||
private final Direction direction;
|
||||
private final RelationshipType type;
|
||||
public RelationshipInfo(String typeName, Direction direction) {
|
||||
this.type = DynamicRelationshipType.withName(typeName);
|
||||
this.direction=direction;
|
||||
}
|
||||
|
||||
public static RelationshipInfo forField(Field field) {
|
||||
final Relationship relationshipAnnotation = field.getAnnotation(Relationship.class);
|
||||
if (relationshipAnnotation!=null) return new RelationshipInfo(relationshipAnnotation.type(),relationshipAnnotation.direction().toNeo4jDir());
|
||||
return new RelationshipInfo(getNeo4jPropertyName(field),Direction.OUTGOING);
|
||||
}
|
||||
|
||||
public RelationshipType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,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;
|
||||
|
||||
// @Property(serialize=SerializationPolicy.STRING, index=true, queryable=true, removeOnReset=true)
|
||||
// Date birthday;
|
||||
@@ -61,18 +67,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import junit.framework.Assert;
|
||||
import org.junit.After;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
@@ -19,12 +20,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;
|
||||
|
||||
@@ -43,44 +48,86 @@ 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();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
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() {
|
||||
Person p = new Person("Michael", 35);
|
||||
Person spouse=new Person("Tina",36);
|
||||
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);
|
||||
Assert.assertEquals(spouse, p.getSpouse());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
@Transactional
|
||||
public void testCreateRelationshipWithAnnotationOnSet() {
|
||||
Person p = new Person("Michael", 35);
|
||||
Person mother=new Person("Gabi",60);
|
||||
Person mother = new Person("Gabi",60);
|
||||
p.setMother(mother);
|
||||
Assert.assertEquals("Gabi", p.getMother().getUnderlyingNode().getProperty("Person.name"));
|
||||
Node motherNode=p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("mother"), org.neo4j.graphdb.Direction.BOTH).getEndNode();
|
||||
Node motherNode = p.getUnderlyingNode().getSingleRelationship(DynamicRelationshipType.withName("mother"), org.neo4j.graphdb.Direction.OUTGOING).getEndNode();
|
||||
Assert.assertEquals(mother.getUnderlyingNode(), motherNode);
|
||||
Assert.assertEquals(mother, p.getMother());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void 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 relationship
|
||||
// TODO test delete previous relationship
|
||||
// TODO test incoming relationship
|
||||
// TODO test bidirectional relationship
|
||||
// TODO test remove property (set to null)
|
||||
@Test
|
||||
@Transactional
|
||||
public void 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());
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
@Transactional
|
||||
public void testBidirectionalRelationshipWithAnnotationOnSet() {
|
||||
Person p = new Person("Michael", 35);
|
||||
Person friend = new Person("David", 25);
|
||||
p.setFriend(friend);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testInstantiatedFinder() {
|
||||
|
||||
Reference in New Issue
Block a user