diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopNodeTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopNodeTypeRepresentationStrategy.java new file mode 100644 index 000000000..32fd2fa7a --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopNodeTypeRepresentationStrategy.java @@ -0,0 +1,46 @@ +package org.springframework.data.graph.neo4j.support; + +import org.neo4j.graphdb.Node; +import org.springframework.data.graph.core.NodeBacked; +import org.springframework.data.graph.core.NodeTypeRepresentationStrategy; + +public class NoopNodeTypeRepresentationStrategy implements NodeTypeRepresentationStrategy { + + @Override + public void postEntityCreation(Node state, Class type) { + } + + @Override + public Iterable findAll(Class clazz) { + throw new UnsupportedOperationException("findAll not supported."); + } + + @Override + public long count(Class entityClass) { + throw new UnsupportedOperationException("count not supported."); + } + + @Override + public void preEntityRemoval(Node state) { + } + + @Override + public Class getJavaType(Node state) { + throw new UnsupportedOperationException("getJavaType not supported."); + } + + @Override + public U createEntity(Node state) { + throw new UnsupportedOperationException("Creation with stored type not supported."); + } + + @Override + public U createEntity(Node state, Class type) { + return projectEntity(state, type); + } + + @Override + public U projectEntity(Node state, Class type) { + return null; + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopRelationshipTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopRelationshipTypeRepresentationStrategy.java new file mode 100644 index 000000000..88167297d --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopRelationshipTypeRepresentationStrategy.java @@ -0,0 +1,46 @@ +package org.springframework.data.graph.neo4j.support; + +import org.neo4j.graphdb.Relationship; +import org.springframework.data.graph.core.RelationshipBacked; +import org.springframework.data.graph.core.RelationshipTypeRepresentationStrategy; + +public class NoopRelationshipTypeRepresentationStrategy implements RelationshipTypeRepresentationStrategy { + + @Override + public void postEntityCreation(Relationship state, Class type) { + } + + @Override + public Iterable findAll(Class clazz) { + throw new UnsupportedOperationException("findAll not supported."); + } + + @Override + public long count(Class entityClass) { + throw new UnsupportedOperationException("count not supported."); + } + + @Override + public void preEntityRemoval(Relationship state) { + } + + @Override + public Class getJavaType(Relationship state) { + throw new UnsupportedOperationException("getJavaType not supported."); + } + + @Override + public U createEntity(Relationship state) { + throw new UnsupportedOperationException("Creation with stored type not supported."); + } + + @Override + public U createEntity(Relationship state, Class type) { + return projectEntity(state, type); + } + + @Override + public U projectEntity(Relationship state, Class type) { + return null; + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategy.java deleted file mode 100644 index e37f28af9..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategy.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.springframework.data.graph.neo4j.support; - -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Relationship; -import org.springframework.data.graph.core.NodeBacked; -import org.springframework.data.graph.core.NodeTypeRepresentationStrategy; -import org.springframework.data.graph.core.RelationshipBacked; -import org.springframework.data.graph.core.RelationshipTypeRepresentationStrategy; - -public class NoopTypeRepresentationStrategy { - public static class NoopNodeStrategy implements NodeTypeRepresentationStrategy { - - @Override - public void postEntityCreation(Node state, Class type) { - } - - @Override - public Iterable findAll(Class clazz) { - throw new UnsupportedOperationException("findAll not supported."); - } - - @Override - public long count(Class entityClass) { - throw new UnsupportedOperationException("count not supported."); - } - - @Override - public void preEntityRemoval(Node state) { - } - - @Override - public Class getJavaType(Node state) { - throw new UnsupportedOperationException("getJavaType not supported."); - } - - @Override - public U createEntity(Node state) { - throw new UnsupportedOperationException("Creation with stored type not supported."); - } - - @Override - public U createEntity(Node state, Class type) { - return projectEntity(state, type); - } - - @Override - public U projectEntity(Node state, Class type) { - return null; - } - } - - public static class NoopRelationshipStrategy implements RelationshipTypeRepresentationStrategy { - - @Override - public void postEntityCreation(Relationship state, Class type) { - } - - @Override - public Iterable findAll(Class clazz) { - throw new UnsupportedOperationException("findAll not supported."); - } - - @Override - public long count(Class entityClass) { - throw new UnsupportedOperationException("count not supported."); - } - - @Override - public void preEntityRemoval(Relationship state) { - } - - @Override - public Class getJavaType(Relationship state) { - throw new UnsupportedOperationException("getJavaType not supported."); - } - - @Override - public U createEntity(Relationship state) { - throw new UnsupportedOperationException("Creation with stored type not supported."); - } - - @Override - public U createEntity(Relationship state, Class type) { - return projectEntity(state, type); - } - - @Override - public U projectEntity(Relationship state, Class type) { - return null; - } - } -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/TypeRepresentationStrategyFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/TypeRepresentationStrategyFactory.java index 83e285282..e00c22243 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/TypeRepresentationStrategyFactory.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/TypeRepresentationStrategyFactory.java @@ -57,7 +57,7 @@ public class TypeRepresentationStrategyFactory { @Override public RelationshipTypeRepresentationStrategy getRelationshipTypeRepresentationStrategy(GraphDatabaseService graphDatabaseService, EntityInstantiator relationshipEntityInstantiator) { - return new NoopTypeRepresentationStrategy.NoopRelationshipStrategy(); + return new NoopRelationshipTypeRepresentationStrategy(); } }, Indexed { @@ -74,12 +74,12 @@ public class TypeRepresentationStrategyFactory { Noop { @Override public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) { - return new NoopTypeRepresentationStrategy.NoopNodeStrategy(); + return new NoopNodeTypeRepresentationStrategy(); } @Override public RelationshipTypeRepresentationStrategy getRelationshipTypeRepresentationStrategy(GraphDatabaseService graphDatabaseService, EntityInstantiator relationshipEntityInstantiator) { - return new NoopTypeRepresentationStrategy.NoopRelationshipStrategy(); + return new NoopRelationshipTypeRepresentationStrategy(); } }; diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyTest.java index 3d5a55848..fae7f2125 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyTest.java @@ -1,7 +1,15 @@ package org.springframework.data.graph.neo4j.support; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.neo4j.graphdb.DynamicRelationshipType; +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.data.graph.annotation.NodeEntity; +import org.springframework.data.graph.annotation.RelationshipEntity; import org.springframework.test.context.CleanContextCacheTestExecutionListener; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; @@ -11,77 +19,109 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml", - "classpath:org/springframework/data/graph/neo4j/support/NoopNodeTypeStrategyOverride-context.xml"}) + "classpath:org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyOverride-context.xml"}) @TestExecutionListeners({CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class}) public class NoopTypeRepresentationStrategyTest { -// -// @Autowired -// private GraphDatabaseContext graphDatabaseContext; -// @Autowired -// private NoopTypeRepresentationStrategy nodeTypeStrategy; -// -// private Thing thing; -// -// @Before -// public void setUp() throws Exception { -// thing = createThing(); -// } + + @Autowired + private GraphDatabaseContext graphDatabaseContext; + @Autowired + private NoopNodeTypeRepresentationStrategy noopNodeStrategy; + @Autowired + private NoopRelationshipTypeRepresentationStrategy noopRelationshipStrategy; + + private Thing thing; + private Link link; + + @Before + public void setUp() throws Exception { + createThing(); + } @Test public void testPostEntityCreation() throws Exception { } -// -// @Test(expected = UnsupportedOperationException.class) -// public void testFindAll() throws Exception { -// nodeTypeStrategy.findAll(Thing.class); -// } -// -// @Test(expected = UnsupportedOperationException.class) -// public void testCount() throws Exception { -// nodeTypeStrategy.count(Thing.class); -// } -// -// @Test(expected = UnsupportedOperationException.class) -// public void testGetJavaType() throws Exception { -// nodeTypeStrategy.getJavaType(node(thing)); -// } -// -// @Test -// public void testPreEntityRemoval() throws Exception { -// nodeTypeStrategy.preEntityRemoval(thing); -// } -// -// @Test -// public void testConfirmType() throws Exception { -// assertEquals(Thing.class, nodeTypeStrategy.confirmType(node(thing), Thing.class)); -// } -// -// private static Node node(Thing thing) { -// return thing.getPersistentState(); -// } -// -// private Thing createThing() { -// Transaction tx = graphDatabaseContext.beginTx(); -// try { -// Node node = graphDatabaseContext.createNode(); -// Thing thing = new Thing(node); -// nodeTypeStrategy.postEntityCreation(thing); -// tx.success(); -// return thing; -// } finally { -// tx.finish(); -// } -// } -// -// @NodeEntity -// public static class Thing { -// String name; -// -// public Thing() { -// } -// -// public Thing(Node n) { -// setPersistentState(n); -// } -// } + + @Test(expected = UnsupportedOperationException.class) + public void testFindAllForNodeStrategy() throws Exception { + noopNodeStrategy.findAll(Thing.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void testFindAllForRelationshipStrategy() throws Exception { + noopRelationshipStrategy.findAll(Link.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void testCountForNodeStrategy() throws Exception { + noopNodeStrategy.count(Thing.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void testCountForRelationshipStrategy() throws Exception { + noopRelationshipStrategy.count(Link.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void testGetJavaTypeOnNodeStrategy() throws Exception { + noopNodeStrategy.getJavaType(null); + } + + @Test(expected = UnsupportedOperationException.class) + public void testGetJavaTypeOnRelationshipStrategy() throws Exception { + noopRelationshipStrategy.getJavaType(null); + } + + @Test + public void testPreEntityRemoval() throws Exception { + noopNodeStrategy.preEntityRemoval(node(thing)); + noopRelationshipStrategy.preEntityRemoval(rel(link)); + } + + private static Node node(Thing thing) { + return thing.getPersistentState(); + } + + private static Relationship rel(Link link) { + return link.getPersistentState(); + } + + private Thing createThing() { + Transaction tx = graphDatabaseContext.beginTx(); + try { + Node node = graphDatabaseContext.createNode(); + thing = new Thing(node); + noopNodeStrategy.postEntityCreation(node, Thing.class); + Relationship rel = node.createRelationshipTo(graphDatabaseContext.createNode(), DynamicRelationshipType.withName("link")); + link = new Link(rel); + noopRelationshipStrategy.postEntityCreation(rel, Link.class); + tx.success(); + return thing; + } finally { + tx.finish(); + } + } + + @NodeEntity + public static class Thing { + String name; + + public Thing() { + } + + public Thing(Node n) { + setPersistentState(n); + } + } + + @RelationshipEntity + public static class Link { + + public Link() { + } + + public Link(Relationship rel) { + setPersistentState(rel); + } + } } diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopNodeTypeStrategyOverride-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyOverride-context.xml similarity index 81% rename from spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopNodeTypeStrategyOverride-context.xml rename to spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyOverride-context.xml index 5a7624d3c..17e8c9de6 100644 --- a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopNodeTypeStrategyOverride-context.xml +++ b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/support/NoopTypeRepresentationStrategyOverride-context.xml @@ -14,5 +14,6 @@ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + + \ No newline at end of file diff --git a/src/docbkx/reference/cross-store.xml b/src/docbkx/reference/cross-store.xml index 3ab1aaa8b..b346de1cc 100644 --- a/src/docbkx/reference/cross-store.xml +++ b/src/docbkx/reference/cross-store.xml @@ -23,10 +23,11 @@ backing graph store afterwards. - The connection between the two entities is kept via a FOREIGN_ID field in the node that contains the JPA id (currently only single - value ids are supported). The entity class can be resolved via the NodeTypeStrategy that preserves the Java type hierarchy within the graph. - With the id and class, you can then retrieve the appropriate JPA entity for a given node. - + The connection between the two entities is kept via a FOREIGN_ID field in the node that contains the JPA id + (currently only single value ids are supported). The entity class can be resolved via the + TypeRepresentationStrategy that manages the Java type hierarchy within the graph. With the id and class, + you can then retrieve the appropriate JPA entity for a given node. + The other direction is handled by indexing the Node with the FOREIGN_ID index which contains a concatenation of the fully qualified class name of the JPA entity and the id. So it is possible on instantiation of a JPA id via the entity manager (or some other means like creating diff --git a/src/docbkx/reference/programming-model/finders.xml b/src/docbkx/reference/programming-model/finders.xml index 4502c538a..a3035ba98 100644 --- a/src/docbkx/reference/programming-model/finders.xml +++ b/src/docbkx/reference/programming-model/finders.xml @@ -2,6 +2,7 @@
Finding nodes with finders + TODO: rewrite to repositories Spring Data Graph also comes with a typed, repository-like Finder implementation that provides methods for locating nodes and relationships. Those methods return instances of the node and relationship entities, not the graph primitives from Neo4j. Finders delegate to the configured NodeTypeStrategy for type @@ -68,15 +69,8 @@ Iterable davesFriends = graphRepository.findAllByTraversal(dave, Internally the mapping from java types to the graph is handled by a NodeTypeStrategy instance that is configured with the GraphDatabaseContext. The strategy is called on entity creation and removal and provides methods for retrieving entities based on type. It also comes with methods confirming or - retrieving java types from the actual graph node. (see also ) - - - The default strategy (IndexingNodeTypeStrategy) - uses indexing (index "__types__") and node properties ("__type__") to store the type information in the graph. - - The second strategy uses an in graph structure to represent the inheritance hierarchy links the actual node - entity nodes to their concrete class nodes. Instance counts are updated on each of the class nodes in the hierarchy. - The last provided strategy is a No-Op strategy that doesn't care about type information. + retrieving java types from the actual graph node. (see also + )
\ No newline at end of file diff --git a/src/docbkx/reference/programming-model/nodetypestrategy.xml b/src/docbkx/reference/programming-model/nodetypestrategy.xml deleted file mode 100644 index ba50c7db6..000000000 --- a/src/docbkx/reference/programming-model/nodetypestrategy.xml +++ /dev/null @@ -1,48 +0,0 @@ - - -
- Storing Type Information in the Graph - - There are several ways to represent the Java type hierarchy of the data model in the graph. In general for all - node and relationship entities type information is needed to perform certain repository operations. Some of - this type information is saved in the graph database. - - - Implementations of NodeTypeStrategy take care of persisting this information on entity instance - creation. They also provide the repository methods that use this type information to perform their operations - like findAll, count, etc. - - - There are three available implementations to choose from. - - - IndexingNodeTypeStrategy - - Stores entity types in the integrated index. Each entity node gets indexed with its type and - any supertypes that are also @NodeEntity-annotated. The special index used for this - is called __types__. Additionally, in order to get the type of an entity node, each - node has a property __type__ with the type of that entity. - - - - SubReferenceNodeTypeStrategy - - Stores entity types in a tree in the graph representing the type hierarchy. Each entity - has a INSTANCE_OF relationship to a type node representing that entity's type. The type may or - may not have a SUBCLASS_OF relationship to another type node. - - - - NoopNodeTypeStrategy - - Does not store any type information, and does hence not support finding by type, counting by type, - or retrieving the type of any entity. - - - - - - The default implementation is IndexingNodeTypeStrategy for new graphs. If using an existing - graph, Spring Data Graph will default to the strategy first used when the graph was created. - -
\ No newline at end of file diff --git a/src/docbkx/reference/programming-model/programming-model.xml b/src/docbkx/reference/programming-model/programming-model.xml index a0c764e90..85af23b1a 100644 --- a/src/docbkx/reference/programming-model/programming-model.xml +++ b/src/docbkx/reference/programming-model/programming-model.xml @@ -14,7 +14,7 @@ - + diff --git a/src/docbkx/reference/programming-model/typerepresentationstrategy.xml b/src/docbkx/reference/programming-model/typerepresentationstrategy.xml new file mode 100644 index 000000000..3fed0354a --- /dev/null +++ b/src/docbkx/reference/programming-model/typerepresentationstrategy.xml @@ -0,0 +1,78 @@ + + +
+ Storing type information in the graph + + There are several ways to represent the Java type hierarchy of the data model in the graph. In general, for all + node and relationship entities, type information is needed to perform certain repository operations. Some of + this type information is saved in the graph database. + + + Implementations of + TypeRepresentationStrategy + take care of persisting this information on entity instance + creation. They also provide the repository methods that use this type information to perform their operations, + like findAll and count. + + + There are three available implementations for node entities to choose from. + + + + IndexingNodeTypeRepresentationStrategy + + + Stores entity types in the integrated index. Each entity node gets indexed with its type and + any supertypes that are also@NodeEntity-annotated. The special index used for this + is called__types__. Additionally, in order to get the type of an entity node, each + node has a property + __type__ + with the type of that entity. + + + + + SubReferenceNodeTypeRepresentationStrategy + + + Stores entity types in a tree in the graph representing the type hierarchy. Each entity + has a INSTANCE_OF relationship to a type node representing that entity's type. The type may or + may not have a SUBCLASS_OF relationship to another type node. + + + + + NoopNodeTypeRepresentationStrategy + + + Does not store any type information, and does hence not support finding by type, counting by type, + or retrieving the type of any entity. + + + + + + There are two implementations for relationship entities available, same behavior as the corresponding ones + above: + + + + IndexingRelationshipTypeRepresentationStrategy + + + + + NoopRelationshipTypeRepresentationStrategy + + + + + + Spring Data Graph will by default autodetect which are the most suitable strategies for node and relationship + entities. For new data stores, it will always opt for the indexing strategies. If a data store was created + with the olderSubReferenceNodeTypeRepresentationStrategy, then it will continue to use that + strategy for node entities. It will however in that case use the no-op strategy for relationship entities, + which means that the old data stores have no support for searching for relationship entities. The indexing + strategies are recommended for all new users. + +
diff --git a/src/docbkx/reference/setup.xml b/src/docbkx/reference/setup.xml index 73706ef56..51ad95a8c 100644 --- a/src/docbkx/reference/setup.xml +++ b/src/docbkx/reference/setup.xml @@ -98,6 +98,7 @@
Setting Up Spring Data Graph - Spring Configuration + Out of date - should we even have this section? The concrete configuration for Spring Data Graph is quite verbose as there is no autowiring involved. It sets up the following parts. @@ -120,7 +121,7 @@ Finder factory - an appropriate NodeTypeStrategy + TypeRepresentationStrategies