jboss-repository
JBoss Public Repository
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedTo.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedTo.java
index 0069041f3..315a81ba7 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedTo.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedTo.java
@@ -16,14 +16,14 @@
package org.springframework.data.graph.annotation;
+import org.springframework.data.graph.core.Direction;
+import org.springframework.data.graph.core.NodeBacked;
+
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.springframework.data.graph.core.Direction;
-import org.springframework.data.graph.core.NodeBacked;
-
/**
* Annotation for {@link org.springframework.data.graph.annotation.NodeEntity} fields that relate to other entities via
* relationships. Works for one-to-one and one-to-many relationships. It is optionally possible to define the relationship type,
@@ -31,10 +31,11 @@ import org.springframework.data.graph.core.NodeBacked;
*
* Collection based one-to-many relationships return managed collections that reflect addition and removal to the underlying relationships.
*
+ * Examples:
*
- * @RelatedTo([type="friends"], elementClass=Person.class)
+ * @RelatedTo(elementClass=Person.class)
* Collection<Person> friends;
- * @RelatedTo([type="spouse"], [elementClass=Person.class])
+ * @RelatedTo(type="partner")
* Person spouse;
*
@@ -47,7 +48,7 @@ public @interface RelatedTo {
/**
* @return name of the relationship type, optional, can be inferred from the field name
*/
- String type();
+ String type() default "";
/**
* @return direction for the relationship, by default outgoing
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedToVia.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedToVia.java
index 318bc997d..1d73667f8 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedToVia.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/annotation/RelatedToVia.java
@@ -52,5 +52,5 @@ public @interface RelatedToVia {
/**
* @return target relationship entity class
*/
- Class extends RelationshipBacked> elementClass() default RelationshipBacked.class;
+ Class extends RelationshipBacked> elementClass();
}
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/config/Neo4jConfiguration.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/config/Neo4jConfiguration.java
index 331903284..1adffa251 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/config/Neo4jConfiguration.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/config/Neo4jConfiguration.java
@@ -17,32 +17,32 @@
package org.springframework.data.graph.neo4j.config;
import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.Node;
import org.neo4j.kernel.impl.transaction.SpringTransactionManager;
import org.neo4j.kernel.impl.transaction.UserTransactionImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean;
import org.springframework.data.graph.neo4j.fieldaccess.NodeDelegatingFieldAccessorFactory;
import org.springframework.data.graph.neo4j.fieldaccess.NodeEntityStateFactory;
import org.springframework.data.graph.neo4j.fieldaccess.RelationshipEntityStateFactory;
import org.springframework.data.graph.neo4j.finder.FinderFactory;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
-import org.springframework.data.graph.neo4j.support.SubReferenceNodeTypeStrategy;
+import org.springframework.data.graph.neo4j.support.NodeTypeStrategyFactoryBean;
import org.springframework.data.graph.neo4j.support.node.Neo4jConstructorGraphEntityInstantiator;
import org.springframework.data.graph.neo4j.support.node.Neo4jNodeBacking;
import org.springframework.data.graph.neo4j.support.node.PartialNeo4jEntityInstantiator;
import org.springframework.data.graph.neo4j.support.relationship.ConstructorBypassingGraphRelationshipInstantiator;
import org.springframework.data.graph.neo4j.support.relationship.Neo4jRelationshipBacking;
import org.springframework.data.graph.neo4j.transaction.ChainedTransactionManager;
-import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.JpaTransactionManager;
-import org.springframework.persistence.transaction.NaiveDoubleTransactionManager;
+import org.springframework.data.persistence.EntityInstantiator;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;
-import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.validation.Validator;
@@ -82,7 +82,7 @@ public class Neo4jConfiguration {
}
public boolean isUsingCrossStorePersistence() {
- return entityManagerFactory!=null;
+ return entityManagerFactory != null;
}
@Bean
@@ -90,20 +90,25 @@ public class Neo4jConfiguration {
GraphDatabaseContext gdc = new GraphDatabaseContext();
gdc.setGraphDatabaseService(getGraphDatabaseService());
gdc.setRelationshipEntityInstantiator(new ConstructorBypassingGraphRelationshipInstantiator());
- if (isUsingCrossStorePersistence()) {
- gdc.setGraphEntityInstantiator(new PartialNeo4jEntityInstantiator(new Neo4jConstructorGraphEntityInstantiator(), entityManagerFactory));
- }
- else {
- gdc.setGraphEntityInstantiator(new Neo4jConstructorGraphEntityInstantiator());
- }
+ EntityInstantiator graphEntityInstantiator = getGraphEntityInstantiator();
+ gdc.setGraphEntityInstantiator(graphEntityInstantiator);
gdc.setConversionService(new Neo4jConversionServiceFactoryBean().getObject());
- gdc.setNodeTypeStrategy(new SubReferenceNodeTypeStrategy(gdc));
+ NodeTypeStrategyFactoryBean nodeTypeStrategyFactoryBean = new NodeTypeStrategyFactoryBean(graphDatabaseService, graphEntityInstantiator);
+ gdc.setNodeTypeStrategy(nodeTypeStrategyFactoryBean.getObject());
if (validator!=null) {
gdc.setValidator(validator);
}
return gdc;
}
+ private EntityInstantiator getGraphEntityInstantiator() {
+ if (isUsingCrossStorePersistence()) {
+ return new PartialNeo4jEntityInstantiator(new Neo4jConstructorGraphEntityInstantiator(), entityManagerFactory);
+ } else {
+ return new Neo4jConstructorGraphEntityInstantiator();
+ }
+ }
+
@Bean
public FinderFactory finderFactory(GraphDatabaseContext graphDatabaseContext) throws Exception {
return new FinderFactory(graphDatabaseContext);
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DefaultEntityState.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DefaultEntityState.java
index ce2615b71..2c9e19766 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DefaultEntityState.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DefaultEntityState.java
@@ -43,8 +43,8 @@ public abstract class DefaultEntityState, STAT
this.entity = entity;
this.type = type;
fieldAccessorFactoryProviders = delegatingFieldAccessorFactory.accessorFactoriesFor(type);
- this.fieldAccessors= fieldAccessorFactoryProviders.getFieldAccessors();
- this.fieldAccessorListeners= fieldAccessorFactoryProviders.getFieldAccessListeners();
+ this.fieldAccessors = fieldAccessorFactoryProviders.getFieldAccessors();
+ this.fieldAccessorListeners = fieldAccessorFactoryProviders.getFieldAccessListeners();
}
@Override
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DelegatingFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DelegatingFieldAccessorFactory.java
index e2996d827..bc48e4bae 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DelegatingFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/DelegatingFieldAccessorFactory.java
@@ -119,11 +119,11 @@ public abstract class DelegatingFieldAccessorFactory implements FieldAccessor
- private final Map, FieldAccessorFactoryProviders> acessorFactoryProviderCache = new HashMap, FieldAccessorFactoryProviders>();
+ private final Map, FieldAccessorFactoryProviders> accessorFactoryProviderCache = new HashMap, FieldAccessorFactoryProviders>();
public FieldAccessorFactoryProviders accessorFactoriesFor(final Class type) {
synchronized (this) {
- final FieldAccessorFactoryProviders fieldAccessorFactoryProviders = acessorFactoryProviderCache.get(type);
+ final FieldAccessorFactoryProviders fieldAccessorFactoryProviders = accessorFactoryProviderCache.get(type);
if (fieldAccessorFactoryProviders != null) return fieldAccessorFactoryProviders;
final FieldAccessorFactoryProviders newFieldAccessorFactories = new FieldAccessorFactoryProviders(type);
ReflectionUtils.doWithFields(type, new ReflectionUtils.FieldCallback() {
@@ -133,7 +133,7 @@ public abstract class DelegatingFieldAccessorFactory implements FieldAccessor
newFieldAccessorFactories.add(field, factory, listenerFactories);
}
});
- acessorFactoryProviderCache.put(type, newFieldAccessorFactories);
+ accessorFactoryProviderCache.put(type, newFieldAccessorFactories);
return newFieldAccessorFactories;
}
}
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeEntityState.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeEntityState.java
index 4f32951ac..bbd5ee7e5 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeEntityState.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeEntityState.java
@@ -21,7 +21,7 @@ import org.neo4j.graphdb.NotInTransactionException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
-import org.springframework.persistence.support.StateProvider;
+import org.springframework.data.persistence.StateProvider;
/**
* @author Michael Hunger
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeRelationshipFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeRelationshipFieldAccessorFactory.java
index 825cc9ce8..6955d2f39 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeRelationshipFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/NodeRelationshipFieldAccessorFactory.java
@@ -18,6 +18,7 @@ package org.springframework.data.graph.neo4j.fieldaccess;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.graph.annotation.RelatedTo;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
@@ -58,12 +59,21 @@ abstract class NodeRelationshipFieldAccessorFactory implements FieldAccessorFact
return DynamicRelationshipType.withName(relAnnotation.type());
}
+ protected DynamicRelationshipType typeFrom(Field field, RelatedTo relAnnotation) {
+ return "".equals(relAnnotation.type()) ? typeFrom(field) : typeFrom(relAnnotation);
+ }
+
protected RelatedTo getRelationshipAnnotation(Field field) {
return field.getAnnotation(RelatedTo.class);
}
protected boolean hasValidRelationshipAnnotation(Field field) {
final RelatedTo relAnnotation = getRelationshipAnnotation(field);
- return relAnnotation != null && !relAnnotation.elementClass().equals(NodeBacked.class);
+ if (relAnnotation == null) return false;
+ boolean hasElementClass = !relAnnotation.elementClass().equals(NodeBacked.class);
+ if (!hasElementClass) throw new InvalidDataAccessApiUsageException(String.format(
+ "Missing mandatory attribute @RelatedTo.elementClass for one-to-N relationship field %s in class: %s",
+ field.getName(), field.getDeclaringClass().getName()));
+ return true;
}
}
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipEntityFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipEntityFieldAccessorFactory.java
index 1f6d6c50c..96552a528 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipEntityFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipEntityFieldAccessorFactory.java
@@ -50,9 +50,15 @@ public class OneToNRelationshipEntityFieldAccessorFactory implements FieldAccess
return new OneToNRelationshipEntityFieldAccessor(typeFrom(relEntityAnnotation), dirFrom(relEntityAnnotation), targetFrom(relEntityAnnotation), graphDatabaseContext);
}
- private boolean hasValidRelationshipAnnotation(final Field f) {
- final RelatedToVia relEntityAnnotation = getRelationshipAnnotation(f);
- return relEntityAnnotation != null && !RelationshipBacked.class.equals(relEntityAnnotation.elementClass());
+ private boolean hasValidRelationshipAnnotation(final Field field) {
+ final RelatedToVia relEntityAnnotation = getRelationshipAnnotation(field);
+ if (relEntityAnnotation == null) return false;
+ Class extends RelationshipBacked> elementClass = relEntityAnnotation.elementClass();
+ boolean hasElementClass = elementClass != null && !RelationshipBacked.class.equals(elementClass);
+ if (!hasElementClass) throw new InvalidDataAccessApiUsageException(String.format(
+ "Missing mandatory attribute @RelatedTo.elementClass for one-to-N relationship field %s in class: %s",
+ field.getName(), field.getDeclaringClass().getName()));
+ return hasElementClass;
}
private RelatedToVia getRelationshipAnnotation(final Field field) {
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessorFactory.java
index 94b274c34..f085d7b19 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/OneToNRelationshipFieldAccessorFactory.java
@@ -44,7 +44,7 @@ public class OneToNRelationshipFieldAccessorFactory extends NodeRelationshipFiel
@Override
public FieldAccessor forField(final Field field) {
final RelatedTo relAnnotation = getRelationshipAnnotation(field);
- return new OneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphDatabaseContext);
+ return new OneToNRelationshipFieldAccessor(typeFrom(field, relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphDatabaseContext);
}
public static class OneToNRelationshipFieldAccessor extends NodeToNodesRelationshipFieldAccessor {
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/PartialNodeEntityState.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/PartialNodeEntityState.java
index bb680595e..424f2400a 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/PartialNodeEntityState.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/PartialNodeEntityState.java
@@ -26,7 +26,7 @@ import org.springframework.data.graph.annotation.RelatedTo;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.finder.FinderFactory;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
-import org.springframework.persistence.support.StateProvider;
+import org.springframework.data.persistence.StateProvider;
import javax.persistence.Id;
import java.lang.reflect.Field;
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/ReadOnlyOneToNRelationshipFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/ReadOnlyOneToNRelationshipFieldAccessorFactory.java
index 70e3c1ace..8c4379108 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/ReadOnlyOneToNRelationshipFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/ReadOnlyOneToNRelationshipFieldAccessorFactory.java
@@ -39,7 +39,7 @@ public class ReadOnlyOneToNRelationshipFieldAccessorFactory extends NodeRelation
@Override
public FieldAccessor forField(final Field field) {
final RelatedTo relAnnotation = getRelationshipAnnotation(field);
- return new ReadOnlyOneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphDatabaseContext);
+ return new ReadOnlyOneToNRelationshipFieldAccessor(typeFrom(field, relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphDatabaseContext);
}
public static class ReadOnlyOneToNRelationshipFieldAccessor extends OneToNRelationshipFieldAccessorFactory.OneToNRelationshipFieldAccessor {
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessorFactory.java
index 54ae107bd..7d97b2565 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessorFactory.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/fieldaccess/SingleRelationshipFieldAccessorFactory.java
@@ -24,7 +24,6 @@ import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
import java.lang.reflect.Field;
-import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@@ -46,7 +45,7 @@ public class SingleRelationshipFieldAccessorFactory extends NodeRelationshipFiel
final RelatedTo relAnnotation = getRelationshipAnnotation(field);
if (relAnnotation == null)
return new SingleRelationshipFieldAccessor(typeFrom(field), Direction.OUTGOING, targetFrom(field), graphDatabaseContext);
- return new SingleRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(field), graphDatabaseContext);
+ return new SingleRelationshipFieldAccessor(typeFrom(field, relAnnotation), dirFrom(relAnnotation), targetFrom(field), graphDatabaseContext);
}
public static class SingleRelationshipFieldAccessor extends NodeToNodesRelationshipFieldAccessor {
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/GraphDatabaseContext.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/GraphDatabaseContext.java
index adfc42d67..ac24b6925 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/GraphDatabaseContext.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/GraphDatabaseContext.java
@@ -29,7 +29,7 @@ import org.springframework.data.graph.core.GraphBacked;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.NodeTypeStrategy;
import org.springframework.data.graph.core.RelationshipBacked;
-import org.springframework.persistence.support.EntityInstantiator;
+import org.springframework.data.persistence.EntityInstantiator;
import javax.transaction.Status;
import javax.transaction.SystemException;
@@ -269,28 +269,6 @@ public class GraphDatabaseContext {
}
- /**
- * @param relType
- * @return
- */
- public Node getOrCreateSubReferenceNode(final RelationshipType relType) {
- return getOrCreateSingleOtherNode(graphDatabaseService.getReferenceNode(), relType, Direction.OUTGOING);
- }
-
- private Node getOrCreateSingleOtherNode(Node fromNode, RelationshipType type,
- Direction direction) {
- Relationship singleRelationship = fromNode.getSingleRelationship(type, direction);
- if (singleRelationship != null) {
- return singleRelationship.getOtherNode(fromNode);
- }
-
- Node otherNode = graphDatabaseService.createNode();
- fromNode.createRelationshipTo(otherNode, type);
- return otherNode;
-
- }
-
-
/**
* @return Neo4j Transaction manager
*/
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java
index 671d30bce..2978c0203 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java
@@ -11,11 +11,14 @@ import org.neo4j.helpers.collection.IterableWrapper;
import org.springframework.data.graph.annotation.NodeEntity;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.NodeTypeStrategy;
-import org.springframework.persistence.support.EntityInstantiator;
+import org.springframework.data.persistence.EntityInstantiator;
public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
- private EntityInstantiator graphEntityInstantiator;
+ public static final String NODE_INDEX_NAME = "__types__";
+ public static final String TYPE_PROPERTY_NAME = "__type__";
+ public static final String INDEX_KEY = "className";
+ private EntityInstantiator graphEntityInstantiator;
private GraphDatabaseService graphDb;
public IndexingNodeTypeStrategy(GraphDatabaseService graphDb, EntityInstantiator graphEntityInstantiator) {
@@ -24,7 +27,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
}
private Index getTypesIndex() {
- return graphDb.index().forNodes("__types__");
+ return graphDb.index().forNodes(NODE_INDEX_NAME);
}
@Override
@@ -32,20 +35,20 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
Node node = entity.getPersistentState();
Class extends NodeBacked> entityClass = entity.getClass();
addToTypesIndex(node, entityClass);
- node.setProperty("__type__", entityClass.getName());
+ node.setProperty(TYPE_PROPERTY_NAME, entityClass.getName());
}
private void addToTypesIndex(Node node, Class extends NodeBacked> entityClass) {
Class> klass = entityClass;
while (klass.getAnnotation(NodeEntity.class) != null) {
- getTypesIndex().add(node, "className", klass.getName());
+ getTypesIndex().add(node, INDEX_KEY, klass.getName());
klass = klass.getSuperclass();
}
}
@Override
public Iterable findAll(Class clazz) {
- final IndexHits allEntitiesOfType = getTypesIndex().get("className", clazz.getName());
+ final IndexHits allEntitiesOfType = getTypesIndex().get(INDEX_KEY, clazz.getName());
return new FilteringIterable(new IterableWrapper(allEntitiesOfType) {
@Override
@SuppressWarnings("unchecked")
@@ -64,7 +67,11 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
@Override
public long count(Class extends NodeBacked> entityClass) {
- return getTypesIndex().get("className", entityClass.getName()).size();
+ long count = 0;
+ for (Node node : getTypesIndex().get(INDEX_KEY, entityClass.getName())) {
+ count += 1;
+ }
+ return count;
}
@Override
@@ -72,7 +79,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
public Class getJavaType(Node node) {
if (node == null) throw new IllegalArgumentException("Node is null");
try {
- return (Class) Class.forName((String) node.getProperty("__type__"));
+ return (Class) Class.forName((String) node.getProperty(TYPE_PROPERTY_NAME));
} catch (NotFoundException e) {
return null;
} catch (ClassNotFoundException e) {
@@ -82,7 +89,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
@Override
public void preEntityRemoval(NodeBacked entity) {
- getTypesIndex().remove(entity.getPersistentState(), "className", entity.getClass().getName());
+ getTypesIndex().remove(entity.getPersistentState());
}
@Override
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java
new file mode 100644
index 000000000..e3d97b7b0
--- /dev/null
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java
@@ -0,0 +1,93 @@
+package org.springframework.data.graph.neo4j.support;
+
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.Node;
+import org.neo4j.graphdb.Relationship;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.data.graph.core.NodeBacked;
+import org.springframework.data.graph.core.NodeTypeStrategy;
+import org.springframework.data.persistence.EntityInstantiator;
+
+public class NodeTypeStrategyFactoryBean implements FactoryBean {
+ private GraphDatabaseService graphDatabaseService;
+ private EntityInstantiator graphEntityInstantiator;
+ private Strategy strategy;
+
+ public NodeTypeStrategyFactoryBean(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) {
+ this.graphDatabaseService = graphDatabaseService;
+ this.graphEntityInstantiator = graphEntityInstantiator;
+ strategy = chooseStrategy();
+ }
+
+ private Strategy chooseStrategy() {
+ if (isAlreadyIndexed()) return Strategy.Indexed;
+ if (isAlreadySubRef()) return Strategy.SubRef;
+ return Strategy.Indexed;
+ }
+
+ private boolean isAlreadyIndexed() {
+ return graphDatabaseService.index().existsForNodes(IndexingNodeTypeStrategy.NODE_INDEX_NAME);
+ }
+
+ private boolean isAlreadySubRef() {
+ for (Relationship rel : graphDatabaseService.getReferenceNode().getRelationships()) {
+ if (rel.getType().name().startsWith(SubReferenceNodeTypeStrategy.SUBREF_PREFIX)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public NodeTypeStrategy getObject() throws Exception {
+ return strategy.getObject(graphDatabaseService, graphEntityInstantiator);
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return strategy.getObjectType();
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false;
+ }
+
+ private enum Strategy {
+ SubRef {
+ @Override
+ NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) {
+ return new SubReferenceNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator);
+ }
+
+ @Override
+ Class extends NodeTypeStrategy> getObjectType() {
+ return SubReferenceNodeTypeStrategy.class;
+ }
+ },
+ Indexed {
+ @Override
+ NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) {
+ return new IndexingNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator);
+ }
+
+ @Override
+ Class extends NodeTypeStrategy> getObjectType() {
+ return IndexingNodeTypeStrategy.class;
+ }
+ },
+ Noop {
+ @Override
+ NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) {
+ return new NoopNodeTypeStrategy();
+ }
+
+ @Override
+ Class extends NodeTypeStrategy> getObjectType() {
+ return NoopNodeTypeStrategy.class;
+ }
+ };
+ abstract NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator);
+ abstract Class extends NodeTypeStrategy> getObjectType();
+ }
+}
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategy.java
index 6aa094180..9cfc3728b 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategy.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategy.java
@@ -25,6 +25,7 @@ import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.NodeTypeStrategy;
+import org.springframework.data.persistence.EntityInstantiator;
import java.util.*;
@@ -47,11 +48,13 @@ public class SubReferenceNodeTypeStrategy implements NodeTypeStrategy {
public static final String SUBREF_PREFIX = "SUBREF_";
public static final String SUBREF_CLASS_KEY = "class";
- private final GraphDatabaseContext graphDatabaseContext;
+ private GraphDatabaseService graphDatabaseService;
+ private EntityInstantiator entityInstantiator;
- public SubReferenceNodeTypeStrategy(final GraphDatabaseContext graphDatabaseContext) {
- this.graphDatabaseContext = graphDatabaseContext;
- }
+ public SubReferenceNodeTypeStrategy(GraphDatabaseService graphDatabaseService, EntityInstantiator entityInstantiator) {
+ this.graphDatabaseService = graphDatabaseService;
+ this.entityInstantiator = entityInstantiator;
+ }
public static Node getSingleOtherNode(Node node, RelationshipType type,
Direction direction) {
@@ -184,7 +187,7 @@ public class SubReferenceNodeTypeStrategy implements NodeTypeStrategy {
@Override
protected T underlyingObjectToObject(final Relationship rel) {
final Node node = rel.getStartNode();
- T entity = (T) graphDatabaseContext.createEntityFromState(node, getJavaType(node));
+ T entity = (T) entityInstantiator.createEntityFromState(node, getJavaType(node));
if (log.isDebugEnabled()) log.debug("Converting node: " + node + " to entity: " + entity);
return entity;
}
@@ -195,15 +198,33 @@ public class SubReferenceNodeTypeStrategy implements NodeTypeStrategy {
public Node obtainSubreferenceNode(final Class> entityClass) {
- return graphDatabaseContext.getOrCreateSubReferenceNode(subRefRelationshipType(entityClass));
+ return getOrCreateSubReferenceNode(subRefRelationshipType(entityClass));
}
public Node findSubreferenceNode(final Class extends NodeBacked> entityClass) {
- final Relationship subrefRelationship = graphDatabaseContext.getReferenceNode().getSingleRelationship(subRefRelationshipType(entityClass), Direction.OUTGOING);
+ final Relationship subrefRelationship = graphDatabaseService.getReferenceNode().getSingleRelationship(subRefRelationshipType(entityClass), Direction.OUTGOING);
return subrefRelationship != null ? subrefRelationship.getEndNode() : null;
}
private DynamicRelationshipType subRefRelationshipType(Class> clazz) {
return DynamicRelationshipType.withName(SUBREF_PREFIX + clazz.getName());
}
+
+ public Node getOrCreateSubReferenceNode(final RelationshipType relType) {
+ return getOrCreateSingleOtherNode(graphDatabaseService.getReferenceNode(), relType, Direction.OUTGOING);
+ }
+
+ private Node getOrCreateSingleOtherNode(Node fromNode, RelationshipType type,
+ Direction direction) {
+ Relationship singleRelationship = fromNode.getSingleRelationship(type, direction);
+ if (singleRelationship != null) {
+ return singleRelationship.getOtherNode(fromNode);
+ }
+
+ Node otherNode = graphDatabaseService.createNode();
+ fromNode.createRelationshipTo(otherNode, type);
+ return otherNode;
+
+ }
+
}
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/Neo4jConstructorGraphEntityInstantiator.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/Neo4jConstructorGraphEntityInstantiator.java
index ba3e4f421..8212d35a8 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/Neo4jConstructorGraphEntityInstantiator.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/Neo4jConstructorGraphEntityInstantiator.java
@@ -18,7 +18,7 @@ package org.springframework.data.graph.neo4j.support.node;
import org.neo4j.graphdb.Node;
import org.springframework.data.graph.core.NodeBacked;
-import org.springframework.persistence.support.AbstractConstructorEntityInstantiator;
+import org.springframework.data.persistence.AbstractConstructorEntityInstantiator;
/**
* Implementation of an entity instantiator for neo4j graphdb nodes, binding the entity type to a NodeBacked and the
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/PartialNeo4jEntityInstantiator.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/PartialNeo4jEntityInstantiator.java
index 3a511de90..59f2409ab 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/PartialNeo4jEntityInstantiator.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/node/PartialNeo4jEntityInstantiator.java
@@ -20,7 +20,7 @@ import org.neo4j.graphdb.Node;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.fieldaccess.PartialNodeEntityState;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
-import org.springframework.persistence.support.EntityInstantiator;
+import org.springframework.data.persistence.EntityInstantiator;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/relationship/ConstructorBypassingGraphRelationshipInstantiator.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/relationship/ConstructorBypassingGraphRelationshipInstantiator.java
index 5ef171ee8..e471d4e7b 100644
--- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/relationship/ConstructorBypassingGraphRelationshipInstantiator.java
+++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/relationship/ConstructorBypassingGraphRelationshipInstantiator.java
@@ -20,7 +20,7 @@ import java.lang.reflect.Constructor;
import org.neo4j.graphdb.Relationship;
import org.springframework.data.graph.core.RelationshipBacked;
-import org.springframework.persistence.support.EntityInstantiator;
+import org.springframework.data.persistence.EntityInstantiator;
import sun.reflect.ReflectionFactory;
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Group.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Group.java
index a5511d84b..db7ecadf3 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Group.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Group.java
@@ -26,7 +26,7 @@ public class Group {
public final static String OTHER_NAME_INDEX="other_name";
public static final String SEARCH_GROUPS_INDEX = "search-groups";
- @RelatedTo(type = "persons", direction = Direction.OUTGOING, elementClass = Person.class)
+ @RelatedTo(direction = Direction.OUTGOING, elementClass = Person.class)
private Collection persons;
@RelatedTo(type = "persons", elementClass = Person.class)
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidOneToNEntity.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidOneToNEntity.java
new file mode 100644
index 000000000..5585d7181
--- /dev/null
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidOneToNEntity.java
@@ -0,0 +1,12 @@
+package org.springframework.data.graph.neo4j;
+
+import org.springframework.data.graph.annotation.NodeEntity;
+import org.springframework.data.graph.annotation.RelatedTo;
+
+import java.util.Collection;
+
+@NodeEntity
+public class InvalidOneToNEntity {
+ @RelatedTo
+ private Collection others;
+}
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidReadOnlyOneToNEntity.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidReadOnlyOneToNEntity.java
new file mode 100644
index 000000000..e1b2993dc
--- /dev/null
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/InvalidReadOnlyOneToNEntity.java
@@ -0,0 +1,10 @@
+package org.springframework.data.graph.neo4j;
+
+import org.springframework.data.graph.annotation.NodeEntity;
+import org.springframework.data.graph.annotation.RelatedTo;
+
+@NodeEntity
+public class InvalidReadOnlyOneToNEntity {
+ @RelatedTo
+ private Iterable others;
+}
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Person.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Person.java
index b250a2ae2..c7c33ff62 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Person.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/Person.java
@@ -44,7 +44,7 @@ public class Person {
private Car car;
- @RelatedTo(type = "mother", direction = Direction.OUTGOING)
+ @RelatedTo
private Person mother;
@RelatedTo(type = "boss", direction = Direction.INCOMING)
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategyTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategyTest.java
index 0353215e3..29b7764e4 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategyTest.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategyTest.java
@@ -24,11 +24,11 @@ import java.util.HashSet;
import java.util.Set;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml",
"classpath:org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategyOverride-context.xml"})
-@Ignore
public class IndexingNodeTypeStrategyTest {
@Autowired
@@ -57,45 +57,76 @@ public class IndexingNodeTypeStrategyTest {
Index typesIndex = graphDatabaseService.index().forNodes("__types__");
IndexHits thingHits = typesIndex.get("className", thing.getClass().getName());
assertEquals(set(node(thing), node(subThing)), IteratorUtil.addToCollection((Iterable)thingHits, new HashSet()));
+ IndexHits subThingHits = typesIndex.get("className", subThing.getClass().getName());
+ assertEquals(node(subThing), subThingHits.getSingle());
assertEquals(thing.getClass().getName(), node(thing).getProperty("__type__"));
assertEquals(subThing.getClass().getName(), node(subThing).getProperty("__type__"));
}
@Test
- public void testFindAll() throws Exception {
- assertEquals("Did not find all things.",
- Arrays.asList(thing, subThing), IteratorUtil.addToCollection(nodeTypeStrategy.findAll(Thing.class), new ArrayList()));
+ public void testPreEntityRemoval() throws Exception {
+ manualCleanDb();
+ createThings();
+ Index typesIndex = graphDatabaseService.index().forNodes("__types__");
+ IndexHits thingHits;
+ IndexHits subThingHits;
+
+ Transaction tx = graphDatabaseService.beginTx();
+ try
+ {
+ nodeTypeStrategy.preEntityRemoval(thing);
+ tx.success();
+ }
+ finally
+ {
+ tx.finish();
+ }
+
+ thingHits = typesIndex.get("className", thing.getClass().getName());
+ assertEquals(node(subThing), thingHits.getSingle());
+ subThingHits = typesIndex.get("className", subThing.getClass().getName());
+ assertEquals(node(subThing), subThingHits.getSingle());
+
+ tx = graphDatabaseService.beginTx();
+ try
+ {
+ nodeTypeStrategy.preEntityRemoval(subThing);
+ tx.success();
+ }
+ finally
+ {
+ tx.finish();
+ }
+
+ thingHits = typesIndex.get("className", thing.getClass().getName());
+ assertNull(thingHits.getSingle());
+ subThingHits = typesIndex.get("className", subThing.getClass().getName());
+ assertNull(subThingHits.getSingle());
}
@Test
+ @Transactional
+ public void testFindAll() throws Exception {
+ assertEquals("Did not find all things.",
+ Arrays.asList(thing, subThing),
+ IteratorUtil.addToCollection(nodeTypeStrategy.findAll(Thing.class), new ArrayList()));
+ }
+
+ @Test
+ @Transactional
public void testCount() throws Exception {
assertEquals(2, nodeTypeStrategy.count(Thing.class));
}
@Test
+ @Transactional
public void testGetJavaType() throws Exception {
assertEquals(Thing.class, nodeTypeStrategy.getJavaType(node(thing)));
assertEquals(SubThing.class, nodeTypeStrategy.getJavaType(node(subThing)));
}
@Test
- public void testPreEntityRemoval() throws Exception {
- manualCleanDb();
- Transaction tx;
- tx = graphDatabaseService.beginTx();
- try {
- nodeTypeStrategy.preEntityRemoval(thing);
- nodeTypeStrategy.preEntityRemoval(subThing);
- tx.success();
- } finally {
- tx.finish();
- }
- Index typesIndex = graphDatabaseService.index().forNodes("__types__");
- IndexHits thingHits = typesIndex.get("className", thing.getClass().getName());
- assertEquals(0, thingHits.size());
- }
-
- @Test
+ @Transactional
public void testConfirmType() throws Exception {
assertEquals(Thing.class, nodeTypeStrategy.confirmType(node(thing), Thing.class));
assertEquals(SubThing.class, nodeTypeStrategy.confirmType(node(subThing), Thing.class));
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NodeEntityRelationshipTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NodeEntityRelationshipTest.java
index e1b022667..2f77f4bb4 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NodeEntityRelationshipTest.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NodeEntityRelationshipTest.java
@@ -61,7 +61,7 @@ public class NodeEntityRelationshipTest {
Person p = persistedPerson("Michael", 35);
Person mother = persistedPerson("Gabi", 60);
p.setMother(mother);
- Node motherNode = p.getPersistentState().getSingleRelationship(DynamicRelationshipType.withName("mother"), Direction.OUTGOING).getEndNode();
+ Node motherNode = p.getPersistentState().getSingleRelationship(DynamicRelationshipType.withName("Person.mother"), Direction.OUTGOING).getEndNode();
assertEquals(mother.getPersistentState(), motherNode);
assertEquals(mother, p.getMother());
}
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/PropertyTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/PropertyTest.java
index 6bad30933..917a732cc 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/PropertyTest.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/PropertyTest.java
@@ -2,19 +2,14 @@ package org.springframework.data.graph.neo4j.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.graph.neo4j.Friendship;
-import org.springframework.data.graph.neo4j.Person;
-import static org.springframework.data.graph.neo4j.Person.persistedPerson;
-import org.springframework.data.graph.neo4j.Personality;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
+import org.springframework.data.graph.neo4j.*;
import org.springframework.data.graph.neo4j.finder.FinderFactory;
import org.springframework.data.graph.neo4j.support.node.Neo4jHelper;
-
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -24,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import static org.junit.Assert.assertEquals;
+import static org.springframework.data.graph.neo4j.Person.persistedPerson;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml"})
@@ -131,4 +127,16 @@ public class PropertyTest {
Friendship f = p.knows(p2);
assertEquals("Wrong ID.", (Long)f.getPersistentState().getId(), f.getRelationshipId());
}
+
+ @Test(expected = InvalidDataAccessApiUsageException.class)
+ @Transactional
+ public void testFailFastOnMisconfiguredOneToNProperty() {
+ new InvalidOneToNEntity();
+ }
+
+ @Test(expected = InvalidDataAccessApiUsageException.class)
+ @Transactional
+ public void testFailFastOnMisconfiguredReadOnlyOneToNProperty() {
+ new InvalidReadOnlyOneToNEntity();
+ }
}
diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategyTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategyTest.java
index ad40b5fb0..f9f51585d 100644
--- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategyTest.java
+++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategyTest.java
@@ -39,7 +39,8 @@ import static org.junit.Assert.assertEquals;
* @since 20.01.11
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml"})
+@ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml",
+ "classpath:org/springframework/data/graph/neo4j/support/SubReferenceNodeTypeStrategyOverride-context.xml"})
public class SubReferenceNodeTypeStrategyTest {
protected final Log log = LogFactory.getLog(getClass());
@@ -48,8 +49,8 @@ public class SubReferenceNodeTypeStrategyTest {
GraphDatabaseContext graphDatabaseContext;
@Autowired
private FinderFactory finderFactory;
-
- private NodeTypeStrategy nodeTypeStrategy;
+ @Autowired
+ private SubReferenceNodeTypeStrategy nodeTypeStrategy;
private Node thingNode;
private Thing thing;
@@ -61,7 +62,6 @@ public class SubReferenceNodeTypeStrategyTest {
@Before
public void setUp() {
- nodeTypeStrategy = graphDatabaseContext.getNodeTypeStrategy();
thingNode = createThing();
}
diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml
index 3f0482541..2a444b96d 100644
--- a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml
+++ b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml
@@ -86,28 +86,30 @@