Permalink
Browse files

updated documentation for spring data neo4j 2.0

  • Loading branch information...
1 parent d806ce1 commit c9996cff4436e685f38a015a58ce632c4f96f8b7 @jexp jexp committed Dec 19, 2011
@@ -3,7 +3,7 @@
<chapter id="reference:aspectj-details">
<title>AspectJ details</title>
<para>
- The object graph mapper of Spring Data Neo4j relies heavily on AspectJ. AspectJ is a Java implementation
+ The advanced mapping mode of Spring Data Neo4j relies heavily on AspectJ. AspectJ is a Java implementation
of the <ulink url="https://secure.wikimedia.org/wikipedia/en/wiki/Aspect-oriented_programming">aspect-oriented
programming</ulink> paradigm that allows easy extraction and controlled application of so-called
cross-cutting concerns. Cross-cutting concerns are typically repetitive tasks in a system (e.g. logging,
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -3,7 +3,8 @@
<chapter id="reference:cross-store">
<title>Cross-store persistence</title>
<para>
- The Spring Data Neo4j project support cross-store persistence, which allows for parts of the data to be
+ The Spring Data Neo4j project support cross-store persistence for the advanced mapping mode,
+ which allows for parts of the data to be
stored in a traditional JPA data store (RDBMS), and other parts in a graph store. This means that an entity
can be partially stored in e.g. MySQL, and partially stored in Neo4j.
</para>
@@ -23,7 +24,7 @@
A backing node in the graph store is only created when the entity has been assigned a JPA ID. Only
then will the association between the two stores be established. Until the entity has been persisted,
its state is just kept inside the POJO (in detached state), and then flushed to the backing graph
- database on <code>persist()</code>.
+ database on the persist operation.
</para>
<para>
The association between the two entities is maintained via a FOREIGN_ID field in the node, that
@@ -8,31 +8,46 @@
of using Spring Data Neo4j instead of the Neo4j API directly.
</para>
<section>
- <title>When is Spring Data Neo4j right</title>
+ <title>When to use Spring Data Neo4j</title>
<para>
The focus of Spring Data Neo4j is to add a convenience layer on top of the Neo4j API. This enables
developers to get up and running with a graph database very quickly, having their domain objects
mapped to the graph with very little work. Building on this foundation, one can later explore other,
more efficient ways to explore and process the graph - if the performance requirements demand it.
</para>
<para>
- Like any other object mapping framework, the domain entities that are created, read, or persisted
+ Like with any other object mapping framework, the domain entities that are created, read, or persisted
represent only a small fraction of the data stored in the database. This is the set needed for a
certain use-case to be displayed, edited or processed in a low throughput fashion. The main advantages
of using an object mapper in this case are the ease of use of real domain objects in your business
- logic and also with existing
+ logic and also the integration with existing
frameworks and libraries that expect Java POJOs as input or create them as results.
</para>
<para>
Spring Data Neo4j, however, was not designed with a major focus on performance. It does add some overhead
- to pure graph operations. Something to keep in mind is that any access of properties and relationships
- will in general read through down to the database. To avoid multiple reads, it is sensible to store the
- result in a local variable in suitable scope (e.g. method, class or jsp).
- </para>
+ to pure graph operations.
+ </para>
<para>
Most of the overhead comes from the use of the Java Reflection API, which is used to provide
information about annotations, fields and constructors. Some of the information is already cached
- by the JVM and the library, so that only the first access gets a performance penalty.
+ by the JVM and the library infrastructure from Spring-Data-Commons, so that only the first access gets a performance penalty.
+ Other reflection penalties like field or method access will occur all the time.
+ </para>
+ <para>
+ For the <emphasis>simple mapping</emphasis> it is important to be aware of the size graph of data that is pulled out of the
+ graph database in a single read and copied to domain entities. That's why Spring Data Neo4j loads
+ related data not by default. You have to provide an indicator (<code>@Fetch</code>) to do so. Alternatively
+ the <code>Neo4jTemplate.fetch</code> method offers means of of loading entities and collections of those.
+ </para>
+ <para>
+ For the <emphasis>advanced mapping mode</emphasis> keep in mind that any access of properties and relationships
+ will in general read through down to the database. To avoid multiple reads, it is sensible to store the
+ result in a local variable in suitable scope (e.g. method, class or jsp).
</para>
+ <para>
+ To evaluate if the performance of Spring Data Neo4j impacts a certain use-case it is sensible to define
+ performance requirements and measure the actual time in realistic test scenarios for the use-case. Only if
+ Spring Data Neo4j doesn't perform as fast as required it is recommended to drop down to the native Neo4j API.
+ </para>
</section>
</chapter>
@@ -1,24 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<section id="reference:programming-model:lifecycle">
- <title>Detached node entities</title>
+ <title>Detached node entities in advanced mapping mode</title>
+ <para>
+ This section only applies to the advanced mapping (AspectJ-backed). The simple mapping always detaches entities on
+ load as it copies the data out of the graph into the entities and stores it back fully too.
+ </para>
<para>
Node entities can be in two different persistence states: attached or detached. By default, newly created node
- entities are in the detached state. When <code>persist()</code> is called on the entity, it becomes
+ entities are in the detached state. When <code>persist() or template.save()</code> is called on the entity, it becomes
attached to the graph, and its properties and relationships are stores in the database. If
- <code>persist()</code> is not called within a transaction, it automatically creates an implicit
- transaction for the operation.
+ the save operation is not called within a transaction, it automatically creates an implicit
+ transaction only for the operation.
</para>
<para>
Changing an attached entity inside a transaction will immediately write through the changes to
the datastore. Whenever an entity is changed outside of a transaction it becomes detached. The
- changes are stored in the entity itself until the next call to <code>persist()</code>.
+ changes are stored in the entity (its fields) itself until the next call to a save operation.
</para>
<para>
All entities returned by library functions are initially in an attached state.
Just as with any other entity, changing them outside of a transaction detaches them, and they
must be reattached with <code>persist()</code> for the data to be saved.
</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="attachdetach.png" scalefit="1" contentwidth="15cm"/>
+ </imageobject>
+ </mediaobject>
+
<!--<para>-->
<!--Persisting an entity not only persists that single entity but will traverse its existing and new relationships-->
<!--and persist the cluster of detached entities that it is part of. The borders of this cluster are formed by-->
@@ -82,7 +93,7 @@ movie.setTopActor(actor);
It is a matter of Java references and is not related to the data model in the database.
</para>
<para>
- The persist operation (merge) stores all properties of the entity to the graph database
+ The save operation (merge) stores all properties of the entity to the graph database
and puts the entity in attached mode. There is no need to update the reference to the Java
POJO as the underlying backing node handles the read-through transparently. If multiple
object instances that point to the same node are persisted, the ordering is not important
@@ -3,11 +3,12 @@
<section id="reference:programming-model:validation">
<title>Bean validation (JSR-303)</title>
<para>
- Spring Data Neo4j supports property-based validation support. When a property is changed, it is
+ Spring Data Neo4j supports property-based validation support. When a property is changed and persisted, it is
checked against the annotated constraints, e.g. <code>@Min</code>, <code>@Max</code>,
<code>@Size</code>, etc. Validation errors throw a <code>ValidationException</code>. The validation
support that comes with Spring is used for evaluating the constraints. To use this feature, a validator
- has to be registered with the <code>GraphDatabaseContext</code>.
+ has to be registered with the <code>Neo4jTemplate</code>, which is done automatically by the <code>Neo4jConfiguration</code>
+ if one is present in the Spring Config.
</para>
<example>
<title>Bean validation</title>
@@ -40,6 +40,26 @@ public class Movie {
</section>
<section>
+ <title>@GraphId: Neo4j -id field</title>
+ <para>
+ For the simple mapping this is a required field which must be of type <code>Long</code>. It is used
+ by Spring Data Neo4j to store the node or relationship-id to re-connect the entity to the graph.
+ </para>
+ <note>
+ <para>
+ It must not be a primitive type because then the "non-attached" case can not be represented as the
+ default value 0 would point to the reference node. Please make also sure that
+ an <code>equals()</code> and <code>hashCode()</code> method have to be provided which take the <code>id</code>
+ field into account (and also handle the "non-attached", null case).
+ </para>
+ </note>
+ <para>
+ For the advanced mapping such a field is optional. Only if the underlying id has to be accessed, it is
+ needed.
+ </para>
+ </section>
+
+ <section>
<title>@GraphProperty: Optional annotation for property fields</title>
<para>
It is not necessary to annotate property fields, as they are persisted by default; all fields that
@@ -314,7 +314,7 @@ Iterable<Person> davesFriends = repo.findAllByTraversal(dave,
<title>Composing repositories</title>
<programlisting language="java"><![CDATA[public interface PersonRepository extends GraphRepository<Person>, PersonRepositoryExtension {}
-// configure the repositories, preferably via the datagraph:repositories namespace
+// configure the repositories, preferably via the neo4j:repositories namespace
// (template reference is optional)
<neo4j:repositories base-package="org.example.repository"
graph-database-context-ref="template"/>
@@ -30,6 +30,13 @@
for classes. Both <code>Neo4jPersistentEntitity</code> as well as <code>Neo4jPersistentProperty</code> provide access to that
information on their scope.
</para>
+ <note>
+ <para>
+ Please note that if you have two collections in an entity pointing to the same relationship and one of them has data and the other is
+ empty due to the nature of persisting it, one will override the other in the graph so that you might end up with no data. If you want
+ a relationship-collection to be ignored on save set it to null.
+ </para>
+ </note>
<para>
<example>
<title>Examples for loading entities from the graph</title>
@@ -82,7 +82,7 @@
</example>
<para>
One can also configure a stock XA transaction manager (e.g. Atomikos, JOTM, App-Server-TM) to be
- used with Neo4j and the other resources. For a bit less secure but fast 1 phase commit best effort,
+ used with Neo4j and the other resources. For a bit less secure but fast 1-phase-commit-best-effort,
use <code>ChainedTransactionManager</code>, which comes bundled with Spring Data Neo4j. It takes a
list of transaction managers as constructor params and will handle them in order for transaction
start and commit (or rollback) in the reverse order.
@@ -8,24 +8,24 @@
this type information is saved in the graph database.
</para>
<para>
- Implementations of <code>TypeRepresentationStrategy</code> take care of persisting this information on entity instance
+ Implementations of <code>TypeRepresentationStrategy</code> take care of persisting this information during entity instance
creation. They also provide the repository methods that use this type information to perform their operations,
- like findAll and count.
+ like <code>findAll</code> and <code>count</code>. The derived finderMethods also use the type information for graph global queries.
</para>
<para>
There are three available implementations for node entities to choose from.
<itemizedlist>
<listitem>
<para>
- <code>IndexingNodeTypeRepresentationStrategy</code>
+ <code>IndexingNodeTypeRepresentationStrategy</code> this is the default strategy used.
</para>
<para>
Stores entity types in the integrated index. Each entity node gets indexed with its type and
any supertypes that are also<code>@NodeEntity</code>-annotated. The special index used for this
is called<code>__types__</code>. Additionally, in order to get the type of an entity node, each
node has a property
<code>__type__</code>
- with the type of that entity.
+ with the fully qualified type of that entity.
</para>
</listitem>
<listitem>
@@ -24,6 +24,10 @@
The unit tests demonstrate some other features of Spring Data Neo4j as well. The sample comes
with a minimal configuration for Maven and Spring to get up and running quickly.
</para>
+ <para>
+ The Hello Worlds application is available both for the simple mapping (<code>hello-worlds</code>)
+ and for the advanced mapping (<code>hello-world-aspects</code>).
+ </para>
<para>
Executing the application creates the following graph in the graph database:
</para>
@@ -42,7 +46,7 @@
roles in different movies. It also uses graph traversal operations to calculate the
<ulink url="http://en.wikipedia.org/wiki/Bacon_number">Bacon number</ulink> of any given actor.
This sample application shows the usage of Spring Data Neo4j in a more complex setting, using several
- annotated entities and relationships as well as indexes and graph traversals.
+ annotated entities and relationships as well as indexes and in-graph indexes and graph traversals.
</para>
<para>
See the readme file for instructions on how to compile and run the application.
@@ -98,5 +102,33 @@
</imageobject>
</mediaobject>
</section>
+ <section id="samples:cineasts">
+ <title>Cineasts social movie database</title>
+ <para>
+ The cineasts.net application was introduced extensively in the first part of this guide, the
+ tutorial. The tutorial covers the development of the simple mapping version of cineasts.
+ </para>
+ <para>
+ To document the differences, versions for the advanced mapping (<code>cineasts-aspects</code>)
+ and accessing the remote server (<code>cineasts-rest</code>) are also available.
+ </para>
+ <para>
+ A online version of cineasts can be found on <ulink url="http://cineasts.net">cineasts.net</ulink>.
+ A sample dataset of the cineasts databse is available at the neo4j <ulink url="http://sample-data.neo4j.org">sample-data page</ulink>.
+ </para>
+ <para>
+ This is a subset of the visualization of the cineasts graph for the "Matrix" movie.
+ </para>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="../tutorial/cineasts_graph.png" contentwidth="15cm" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="../tutorial/cineasts_main.png" contentwidth="15cm" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </section>
</chapter>
Oops, something went wrong.

0 comments on commit c9996cf

Please sign in to comment.