Merge branch 'master' into snapshot
This commit is contained in:
@@ -102,7 +102,7 @@
|
||||
<xi:include href="reference/samples.xml"/>
|
||||
<xi:include href="reference/performance.xml" />
|
||||
<xi:include href="reference/template.xml" />
|
||||
<xi:include href="reference/aspectj-intro.xml" />
|
||||
<xi:include href="reference/aspectj-details.xml" />
|
||||
<xi:include href="reference/neo4j-server.xml" />
|
||||
</part>
|
||||
</book>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="reference:aspectj-intro">
|
||||
<title>AspectJ introduction</title>
|
||||
<chapter id="reference:aspectj-details">
|
||||
<title>AspectJ details</title>
|
||||
<para>
|
||||
The object graph mapper of Spring Data Graph relies heavily on AspectJ. AspectJ is the Java implementation of
|
||||
the <ulink url="https://secure.wikimedia.org/wikipedia/en/wiki/Aspect-oriented_programming">Aspect
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="cross-store">
|
||||
<title>Cross-store persistence with a graph database</title>
|
||||
<title>Cross-store persistence</title>
|
||||
<para>The Spring Data Graph project support cross-store persistence which allows parts of the data mode to be stored in a traditional
|
||||
JPA datastore (RDBMS) and other parts of the data model (even partial entites, that is some properties or relationships) in a graph
|
||||
store.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<title>Overview of the AspectJ support</title>
|
||||
<title>AspectJ support</title>
|
||||
<para>
|
||||
Behind the scenes, Spring Data Graph leverages <ulink url="http://www.eclipse.org/aspectj/">AspectJ</ulink>
|
||||
aspects to modify the behavior of simple annotated POJO entities
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<title>Session handling - attached and detached entities</title>
|
||||
<title>Detached entities</title>
|
||||
<para>
|
||||
By default newly created node entities are in a detached state. When <code>persist()</code> is called on the
|
||||
entity it is attached to the graph store and its properties and relationships are persisted as well. Changing
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<title>Bean Validation - JSR-303</title>
|
||||
<title>Bean validation (JSR-303)</title>
|
||||
<para>
|
||||
Spring Data Graph supports property based validation support. So, whenever a property is changed, it is
|
||||
checked against the annotated constraints (.e.g @Min, @Max, @Size, etc).
|
||||
|
||||
@@ -1,135 +1,142 @@
|
||||
<?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:indexing">
|
||||
<section id="reference:programming-model:indexing">
|
||||
<title>Indexing</title>
|
||||
|
||||
<para>
|
||||
The Neo4j graph database can use different index providers for exact lookups and fulltext searches. Lucene is
|
||||
used as default index provider implementation. There is support for distinct indexes for nodes and relationships
|
||||
which can be configured to be of fulltext or exact types.
|
||||
The Neo4j graph database can use different so-called index providers for exact lookups and fulltext
|
||||
searches. Lucene is the default index provider implementation. Each named index is configured to be
|
||||
fulltext or exact.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Exact and Numeric Index</title>
|
||||
<para>
|
||||
Using the standard Neo4j API, Nodes and Relationships and their indexed field-value combinations
|
||||
have to be added manually to the appropriate index. When using Spring Data Graph, this task is simplified by
|
||||
eased by applying an <code>@Indexed</code> annotation on entity fields. This will result in updates to the
|
||||
index on every change.
|
||||
</para><para>
|
||||
Numerical fields are indexed numerically so that they are available for range queries.
|
||||
All other fields are indexed with their string representation.
|
||||
</para><para>
|
||||
The @Indexed annotation can also set the
|
||||
index-name to be used the default index name is the simple class name of the entity. So the same field names
|
||||
from different classes don't end up in the same index by default. That would return different domain objects
|
||||
for a single index query.
|
||||
</para>
|
||||
<para>
|
||||
Query access to the index happens with the Node- and Relationship-Repostories that are created via an instance of
|
||||
<code>org.springframework.data.graph.neo4j.repository.DirectGraphRepositoryFactory</code>. The methods
|
||||
<code>findByPropertyValue</code> and <code>findAllByPropertyValue</code> work on the exact indexes and
|
||||
return the first or all matches. To do range queries, use <code>findAllByRange</code> (please note that
|
||||
currently both values are inclusive).
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[
|
||||
<title>Exact and numeric index</title>
|
||||
<para>
|
||||
When using the standard Neo4j API, nodes and relationships have to be manually indexed with
|
||||
key-value pairs, typically being the property name and value. When using Spring Data Graph,
|
||||
this task is simplified to just adding an <code>@Indexed</code> annotation on entity fields
|
||||
by which the entity should be searchable. This will result in automatic updates of the index
|
||||
every time an indexed field changes.
|
||||
</para>
|
||||
<para>
|
||||
Numerical fields are indexed numerically so that they are available for range queries. All
|
||||
other fields are indexed with their string representation.
|
||||
</para>
|
||||
<para>
|
||||
The @Indexed annotation also provides the option of using a custom index. The default index
|
||||
name is the simple class name of the entity, so that each class typically gets its own index.
|
||||
It is recommended to not have two entity classes with the same class name, regardless of
|
||||
package.
|
||||
</para>
|
||||
<para>
|
||||
The indexes can be queried by using a repository (see <xref linkend="reference:repositories" />).
|
||||
Typically, the repository is an instance of
|
||||
<code>org.springframework.data.graph.neo4j.repository.DirectGraphRepositoryFactory</code>.
|
||||
The methods <code>findByPropertyValue()</code> and <code>findAllByPropertyValue()</code> work on
|
||||
the exact indexes and return the first or all matches. To do range queries, use
|
||||
<code>findAllByRange()</code> (please note that currently both values are inclusive).
|
||||
</para>
|
||||
<example>
|
||||
<title>Indexing entities</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
@NodeEntity
|
||||
class Person {
|
||||
@Indexed(indexName = "people")
|
||||
String name;
|
||||
|
||||
// automatically indexed numerically
|
||||
@Indexed
|
||||
int age;
|
||||
|
||||
@Indexed(indexName = "people") String name;
|
||||
@Indexed int age;
|
||||
}
|
||||
|
||||
GraphRepository<Person> graphRepository = graphRepositoryFactory.createGraphRepository(Person.class);
|
||||
|
||||
// exact graphRepository
|
||||
Person mark = graphRepository.findByProperyValue("people","name","mark");
|
||||
// Exact match, in named index
|
||||
Person mark = graphRepository.findByPropertyValue("people", "name", "mark");
|
||||
|
||||
// numeric range queries
|
||||
for (Person middleAgedDeveloper : graphRepository.findAllByRange( "age", 20, 40)) {
|
||||
// Numeric range query, index name inferred automatically
|
||||
for (Person middleAgedDeveloper : graphRepository.findAllByRange("age", 20, 40)) {
|
||||
Developer developer=middleAgedDeveloper.projectTo(Developer.class);
|
||||
}
|
||||
]]></programlisting>
|
||||
</section>
|
||||
</example>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<title>Fulltext Indexes</title>
|
||||
<title>Fulltext indexes</title>
|
||||
<para>
|
||||
Spring Data Graph also supports full-text indexes. By default indexed fields are stored in an exact-lookup
|
||||
index. To have them analyzed and prepared for fulltext search, the <code>@Indexed</code> annotation has
|
||||
the boolean <code>fulltext</code> attribute. Please note that fulltext-indexes require a separate index name
|
||||
as the fulltext-configuration is stored in the index itself.
|
||||
Spring Data Graph also supports fulltext indexes. By default, indexed fields are stored in
|
||||
an exact lookup index. To have them analyzed and prepared for fulltext search, the
|
||||
<code>@Indexed</code> annotation has the boolean <code>fulltext</code> attribute.
|
||||
|
||||
Please note that fulltext indexes require a separate index name as the fulltext configuration
|
||||
is stored in the index itself.
|
||||
</para>
|
||||
<para>
|
||||
Access to the fulltext index is provided by the <code>findAllByQuery</code> method of the repositories. Wildcard
|
||||
like * are allowed. Otherwise the fulltext querying rules of the underlying index provider apply. (In most
|
||||
cases this will be lucene.
|
||||
Access to the fulltext index is provided by the <code>findAllByQuery()</code> repository method.
|
||||
Wildcards like <code>*</code> are allowed. Generally though, the fulltext querying rules of the
|
||||
underlying index provider apply. See the
|
||||
<ulink url="http://lucene.apache.org/java/3_0_1/">Lucene documentation</ulink> for more
|
||||
information on this.
|
||||
</para>
|
||||
<para>
|
||||
<programlisting language="java"><![CDATA[
|
||||
<example>
|
||||
<title>Fulltext indexing</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
@NodeEntity
|
||||
class Person {
|
||||
@Indexed(indexName = "person-name", fulltext=true)
|
||||
String name;
|
||||
@Indexed(indexName = "person-name", fulltext=true) String name;
|
||||
}
|
||||
|
||||
GraphRepository<Person> graphRepository = graphRepositoryFactory.createGraphRepository(Person.class);
|
||||
|
||||
// exact graphRepository
|
||||
Person mark = graphRepository.findAllByQuery("people-search","name","ma*");
|
||||
Person mark = graphRepository.findAllByQuery("people-search", "name", "ma*");
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
Please note that indexes are currently created on demand, so whenever an index that doesn't exist
|
||||
is requested from a query or get operation it is created. This is subject to change but has currently
|
||||
the implication that those indexes won't be configured as fulltext which causes subsequent fulltext-
|
||||
updates to those indexes to fail.
|
||||
</para>
|
||||
Please note that indexes are currently created on demand, so whenever an index that doesn't exist
|
||||
is requested from a query or get operation it is created. This is subject to change but has
|
||||
currently the implication that those indexes won't be configured as fulltext which causes
|
||||
subsequent fulltext updates to those indexes to fail.
|
||||
</note>
|
||||
</section>
|
||||
<section>
|
||||
<title>Raw Index Access</title>
|
||||
<para>The raw index for a domain class is also available from <code>GraphDatabaseContext</code> via the
|
||||
<code>getIndex</code> method. The second parameter is optional and takes the index-name if it doesn't default
|
||||
to the simple domain class name. It returns the Index implementation that is provided by Neo4j.
|
||||
<title>Manual index access</title>
|
||||
<para>
|
||||
The index for a domain class is also available from <code>GraphDatabaseContext</code> via
|
||||
the <code>getIndex()</code> method. The second parameter is optional and takes the index name
|
||||
if it should not be inferred from the class name. It returns the index implementation that is
|
||||
provided by Neo4j.
|
||||
</para>
|
||||
<example>
|
||||
<title>Manual index usage</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
@Autowired GraphDatabaseContext gdc;
|
||||
|
||||
// exact index
|
||||
Index<Node> personIndex=gdc.getIndex(Person.class,null);
|
||||
personIndex.add(node,"name","Mark");
|
||||
// Default index
|
||||
Index<Node> personIndex = gdc.getIndex(Person.class);
|
||||
personIndex.query(new QueryContext(NumericRangeQuery.newÍntRange("age", 20, 40, true, true))
|
||||
.sort(new Sort(new SortField("age", SortField.INT, false))));
|
||||
|
||||
Index<Node> namedPersonIndex=gdc.getIndex(Person.class,"people");
|
||||
namedPersonIndex.get("name","Mark");
|
||||
// Named index
|
||||
Index<Node> namedPersonIndex = gdc.getIndex(Person.class, "people");
|
||||
namedPersonIndex.get("name", "Mark");
|
||||
|
||||
// complex range & sort query
|
||||
namedPersonIndex.query( new QueryContext( NumericRangeQuery.newÍntRange( "age", 20, 40, true, true ) )
|
||||
.sort( new Sort( new SortField( "age", SortField.INT, false ) ) ) );
|
||||
|
||||
// fulltext index
|
||||
Index<Node> personFulltextIndex=gdc.getIndex(Person.class,"person-name",true);
|
||||
namedPersonIndex.query("name","Ma*");
|
||||
namedPersonIndex.query("{name:Ma*}");
|
||||
|
||||
]]></programlisting>
|
||||
|
||||
</para>
|
||||
// Fulltext index
|
||||
Index<Node> personFulltextIndex = gdc.getIndex(Person.class, "person-name", true);
|
||||
personFulltextIndex.query("name", "*cha*");
|
||||
personFulltextIndex.query("{name:*cha*}");
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section>
|
||||
<title>Indexing in Neo4jTemplate</title>
|
||||
<para>
|
||||
Neo4jTemplate also offers index support, providing auto-indexing for fields at creation time of nodes and
|
||||
relationships. There is an <code>autoIndex</code> method that can also add indexes for a set of fields in one
|
||||
go.
|
||||
Neo4jTemplate also offers index support, providing auto-indexing for fields at creation time.
|
||||
There is an <code>autoIndex</code> method that can also add indexes for a set of fields in one go.
|
||||
</para>
|
||||
<para>
|
||||
For querying the index, the template offers query-methods that take either the exact match parameters or a query
|
||||
object / query expression and push the results wrapped uniformly as Paths to the supplied
|
||||
<code>PathMapper</code> to be converted or collected.
|
||||
For querying the index, the template offers query methods that take either the exact match
|
||||
parameters or a query object/expression, and push the results wrapped uniformly as Paths to
|
||||
the supplied <code>PathMapper</code> to be converted or collected.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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:introduced-methods">
|
||||
<title>Methods added to entity classes</title>
|
||||
<title>Introduced methods</title>
|
||||
<para>
|
||||
The node and relationship aspects introduce (via AspectJ ITD - inter type declaration) several
|
||||
methods to the entities.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?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:annotations">
|
||||
<title>Annotations define POJO node entities</title>
|
||||
<para>Entities are declared using the <code>@NodeEntity</code> annotation.
|
||||
Relationship entities use the <code>@RelationshipEntity</code> annotation.
|
||||
<title>Defining node entities</title>
|
||||
<para>
|
||||
Node entities are declared using the <code>@NodeEntity</code> annotation. Relationship entities use
|
||||
the <code>@RelationshipEntity</code> annotation.
|
||||
</para>
|
||||
<section>
|
||||
<title>@NodeEntity: The basic building block</title>
|
||||
@@ -61,7 +62,7 @@ String title;
|
||||
<para>
|
||||
Numerical values are indexed as such by default, allowing for range queries.
|
||||
Fulltext indexing is also possible by setting the <code>fulltext</code> attribute to true. For details see
|
||||
the indexing section <xref linkend="reference_programming-model:indexing"/>.
|
||||
the indexing section <xref linkend="reference:programming-model:indexing"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="programming-model" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<title>Programming model for Spring Data Graph</title>
|
||||
<title>Programming model</title>
|
||||
<para>
|
||||
This chapter covers the fundamentals of the programming model behind Spring Data Graph. It discusses the
|
||||
AspectJ features used and the annotations provided by Spring Data Graph and how to use them.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<title>Dynamic typing - Projection to unrelated, fitting types</title>
|
||||
<title>Projecting entities</title>
|
||||
<para>
|
||||
As the underlying data model of a graph database doesn't imply and enforce strict type constraints like a
|
||||
relational model does, it offers much more flexibility on how to model your domain classes and which of
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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:relationships">
|
||||
<title>Relationships relate node entities</title>
|
||||
<title>Relating node entities</title>
|
||||
<para>
|
||||
Since relationships are first-class citizens in Neo4j, associations between node entities are represented
|
||||
by relationships. In general, relationships are categorized by a type, and start and end nodes (which
|
||||
@@ -9,13 +9,6 @@
|
||||
Spring Data Graph has special support to represent Neo4j relationships as entities too, but it is often
|
||||
not needed.
|
||||
</para>
|
||||
<section>
|
||||
<title>@NodeEntity</title>
|
||||
<para>
|
||||
Any class annotated with @NodeEntity will be backed by a node in the graph. Its fields will, if their
|
||||
types are supported, be persisted as properties to the node for each entity.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>@RelatedTo: Connecting node entities</title>
|
||||
<para>
|
||||
|
||||
@@ -1,142 +1,154 @@
|
||||
<?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>
|
||||
<title>GraphRepositories for basic CRUD and find-operations</title>
|
||||
<section id="reference:repositories">
|
||||
<title>CRUD with repositories</title>
|
||||
<para>
|
||||
The repositories provided by Spring Data Graph build on the composable repository infrastructure contained
|
||||
The repositories provided by Spring Data Graph build on the composable repository infrastructure
|
||||
in <ulink url="http://static.springsource.org/spring-data/data-jpa/docs/1.0.0.M2/reference/html/#repositories.custom-implementations">Spring Data Commons</ulink>.
|
||||
Those repositories allow the interface based composition of the final repository consisting of provided default
|
||||
They allow for interface based composition of repositories consisting of provided default
|
||||
implementations for certain interfaces and additional custom implementations for other methods.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
Spring Data Graph provides only the infrastructure and some default repository implementations so far. In future
|
||||
releases support for finders derived from method names, named queries and annotated query methods will be added.
|
||||
Spring Data Graph provides only the infrastructure and some default repository implementations
|
||||
so far. Future releases will support finders derived from method names, named queries, and
|
||||
annotated query methods.
|
||||
(e.g.
|
||||
findByName(name),
|
||||
@Query(name = "find-by-name-query") findByName(name),
|
||||
@Query(query = "{name:%s}") findByName(name))
|
||||
<code>findByName(name)</code>,
|
||||
<code>@Query(name="find-by-name-query") findByName(name)</code>, and
|
||||
<code>@Query(query="{name:%s}") findByName(name)</code>)
|
||||
</para>
|
||||
</note>
|
||||
<para>Spring Data Graph comes with typed repository implementations that provide methods for
|
||||
locating node and relationship entities. There are 3 types of basic repository interfaces and implementations.
|
||||
One CRUD-Repository (<code>CRUDGraphRepository<T></code>) that provides basic operations, a <code>IndexQueryExecutor</code>
|
||||
that delegates to Neo4j's internal indexing subsystem for executing queries. And last but not least
|
||||
a <code>TraversalQueryExecutor</code> that handles Neo4J Traversals.
|
||||
<para>
|
||||
Spring Data Graph comes with typed repository implementations that provide methods for
|
||||
locating node and relationship entities. There are 3 types of basic repository interfaces
|
||||
and implementations. <code>CRUDRepository</code> provides basic operations,
|
||||
<code>IndexRepository</code> and <code>NamedIndexRepository</code> delegate to Neo4j's internal
|
||||
indexing subsystem for queries, and <code>TraversalRepository</code> handles Neo4j traversals.
|
||||
</para>
|
||||
<para>
|
||||
<code>CRUDGraphRepository</code> delegates to the configured <code>TypeRepresentationStrategy</code>
|
||||
(<xref linkend="reference:programming-model:typerepresentationstrategy"/>)
|
||||
<code>CRUDRepository</code> delegates to the configured <code>TypeRepresentationStrategy</code>
|
||||
(see <xref linkend="reference:programming-model:typerepresentationstrategy"/>)
|
||||
for type based queries.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>loading an instance via the Neo4j node id</term>
|
||||
<listitem> <para> <code>T findOne(id)</code></para> </listitem>
|
||||
<term>Load an instance via a Neo4j node id</term>
|
||||
<listitem><para><code>T findOne(id)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>checks for existence via the Neo4j node id</term>
|
||||
<listitem> <para> <code>boolean exists(id)</code></para> </listitem>
|
||||
<term>Check for existence of a Neo4j node id</term>
|
||||
<listitem><para><code>boolean exists(id)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>iterating over all nodes of a node entity type</term>
|
||||
<listitem> <para> <code>Iterable<T> findAll()</code> (supported in future versions: <code>Iterable<T> findAll(Sort)</code> and <code>Page<T> findAll(Pageable)</code>)</para> </listitem>
|
||||
<term>Iterate over all nodes of a node entity type</term>
|
||||
<listitem><para><code>Iterable<T> findAll()</code>
|
||||
(supported in future versions:
|
||||
<code>Iterable<T> findAll(Sort)</code> and
|
||||
<code>Page<T> findAll(Pageable)</code>)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>counting the instances of a node entity type</term>
|
||||
<listitem> <para> <code>Long count()</code> </para> </listitem>
|
||||
<term>Count the instances of a node entity type</term>
|
||||
<listitem><para><code>Long count()</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>saves the graph entities</term>
|
||||
<listitem> <para> <code>T save(T)</code> and <code>Iterable<T> save(Iterable<T>)</code> </para> </listitem>
|
||||
<term>Save a graph entity</term>
|
||||
<listitem><para><code>T save(T)</code> and <code>Iterable<T> save(Iterable<T>)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>deletes the graph entities</term>
|
||||
<listitem> <para> <code>void delete(T)</code>, <code>void; delete(Iterable<T>)</code> and <code>deleteAll()</code></para> </listitem>
|
||||
<term>Delete a graph entity</term>
|
||||
<listitem><para><code>void delete(T)</code>, <code>void; delete(Iterable<T>)</code>,
|
||||
and <code>deleteAll()</code></para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
<para>
|
||||
<code>IndexQueryExecutor</code> works with the indexing subsystem and provides methods to find entities by indexed properties, ranged queries of combination thereof.
|
||||
</para>
|
||||
<para>
|
||||
<code>IndexRepository</code> works with the indexing subsystem and provides methods to find
|
||||
entities by indexed properties, ranged queries, and combinations thereof. The index key is
|
||||
the name of the indexed entity field, unless overridden in the <code>@Indexed</code> annotation.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>iterating over all indexed instances with a certain property value</term>
|
||||
<listitem> <para> <code>Iterable<T> findAllByPropertyValue(indexName, keyName, value)</code> </para> </listitem>
|
||||
<term>Iterate over all indexed entity instances with a certain field value</term>
|
||||
<listitem><para><code>Iterable<T> findAllByPropertyValue(key, value)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>getting a single instance with a certain property value</term>
|
||||
<listitem> <para> <code>T findByPropertyValue(indexName, keyName, value)</code> </para> </listitem>
|
||||
<term>Get a single entity instance with a certain field value</term>
|
||||
<listitem><para><code>T findByPropertyValue(key, value)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>iterating over all indexed instances within a certain numerical range (inclusive)</term>
|
||||
<listitem> <para> <code>Iterable<T> findAllByRange(indexName, keyName, from, to)</code> </para> </listitem>
|
||||
<term>Iterate over all indexed entity instances with field values in a certain numerical range (inclusive)</term>
|
||||
<listitem><para><code>Iterable<T> findAllByRange(key, from, to)</code></para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>iterating over all indexed instances matching the given fulltext (or QueryContext query)</term>
|
||||
<listitem> <para> <code>Iterable<T> findAllByQuery(indexName, keyName, queryOrQueryContext)</code> </para> </listitem>
|
||||
<term>Iterate over all indexed entity instances with field values matching the given fulltext string or QueryContext query</term>
|
||||
<listitem><para><code>Iterable<T> findAllByQuery(key, queryOrQueryContext)</code></para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</variablelist>
|
||||
There is also a <code>NamedIndexRepository</code> with the same methods, but with an additional index
|
||||
name parameter, making it possible to query any index.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<code>TraversalQueryExecutor</code> works with the traversal framework.
|
||||
<code>TraversalRepository</code> delegates to the Neo4j traversal framework.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>iterating over a traversal result</term>
|
||||
<listitem> <para> <code>Iterable<T> findAllByTraversal(startNode, traversalDescription)</code> </para> </listitem>
|
||||
<term>Iterate over a traversal result</term>
|
||||
<listitem><para><code>Iterable<T> findAllByTraversal(startEntity, traversalDescription)</code></para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
The <code>Repository</code> instances are either created manually via a DirectGraphRepositoryFactory to be bound
|
||||
o a concrete node or relationship entity class.
|
||||
The <code>Repository</code> instances are either created manually via a
|
||||
<code>DirectGraphRepositoryFactory</code>, bound to a concrete node or relationship entity class.
|
||||
The <code>DirectGraphRepositoryFactory</code> is configured in the Spring context and can be injected.
|
||||
<example>
|
||||
<title>Using GraphRepositories</title>
|
||||
</para>
|
||||
<example>
|
||||
<title>Using GraphRepositories</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
GraphRepository<Person> graphRepository = graphRepositoryFactory.createGraphRepository(Person.class);
|
||||
|
||||
Person michael = graphRepository.save(new Person("Michael",36));
|
||||
Person michael = graphRepository.save(new Person("Michael", 36));
|
||||
|
||||
Person dave=graphRepository.findOne(123);
|
||||
Person dave = graphRepository.findOne(123);
|
||||
|
||||
Long numberOfPeople = graphRepository.count();
|
||||
|
||||
Person mark = graphRepository.findByPropertyValue("name", "mark");
|
||||
|
||||
Iterable<Person> devs = graphRepository.findAllByProperyValue("occupation","developer");
|
||||
Iterable<Person> devs = graphRepository.findAllByProperyValue("occupation", "developer");
|
||||
|
||||
Iterable<Person> middleAgedPeople = graphRepository.findAllByRange("age",20,40);
|
||||
Iterable<Person> middleAgedPeople = graphRepository.findAllByRange("age", 20, 40);
|
||||
|
||||
Iterable<Person> aTeam = graphRepository.findAllByQuery("name","A*");
|
||||
Iterable<Person> aTeam = graphRepository.findAllByQuery("name", "A*");
|
||||
|
||||
Iterable<Person> davesFriends = graphRepository.findAllByTraversal(dave,
|
||||
Traversal.description().pruneAfterDepth(1)
|
||||
.relationships(KNOWS).filter(returnAllButStartNode()));
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</para>
|
||||
</example>
|
||||
<section>
|
||||
<title>Composing Repositories</title>
|
||||
<para>
|
||||
The recommended way of providing repositories is to define a repository-interface per domain class and have the
|
||||
mechanisms provided by the repository infrastructure automatically detect them and additional implementation
|
||||
classes and create an injectable repository implementation to be used in services or other spring beans.
|
||||
<title>Composing repositories</title>
|
||||
<para>
|
||||
The recommended way of providing repositories is to define a repository interface per domain
|
||||
class. The mechanisms provided by the repository infrastructure will automatically detect
|
||||
them, along with additional implementation classes, and create an injectable repository
|
||||
implementation to be used in services or other spring beans.
|
||||
</para>
|
||||
<example>
|
||||
<title>Composing Repositories</title>
|
||||
<title>Composing repositories</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
public interface PersonRepository extends GraphRepository<Person>, PersonRepositoryExtension {
|
||||
}
|
||||
public interface PersonRepository extends GraphRepository<Person>, PersonRepositoryExtension {}
|
||||
|
||||
// alternatively select some of the required repositories individually
|
||||
public interface PersonRepository extends CRUDGraphRepository<Node,Person>, IndexQueryExecutor<Node,Person>,
|
||||
TraversalQueryExecutor<Node,Person>, PersonRepositoryExtension {
|
||||
}
|
||||
TraversalQueryExecutor<Node,Person>, PersonRepositoryExtension {}
|
||||
|
||||
// provide a custom extension if needed
|
||||
public interface PersonRepositoryExtension {
|
||||
Iterable<Person> findFriends(Person person);
|
||||
}
|
||||
public class PersonRepositoryImpl implements PersonRepositoryExtension {
|
||||
|
||||
public class PersonRepositoryImpl implements PersonRepositoryExtension {
|
||||
// optionally inject default repository, or use DirectGraphRepositoryFactory
|
||||
@Autowired PersonRepository baseRepository;
|
||||
public Iterable<Person> findFriends(Person person) {
|
||||
@@ -151,18 +163,17 @@ public class PersonRepositoryImpl implements PersonRepositoryExtension {
|
||||
@Autowired
|
||||
PersonRepository personRepository;
|
||||
|
||||
Person michael = personRepository.save(new Person("Michael",36));
|
||||
Person michael = personRepository.save(new Person("Michael",36));
|
||||
|
||||
Person dave=personRepository.findOne(123);
|
||||
Person dave=personRepository.findOne(123);
|
||||
|
||||
Iterable<Person> devs = personRepository.findAllByProperyValue("occupation","developer");
|
||||
Iterable<Person> devs = personRepository.findAllByProperyValue("occupation","developer");
|
||||
|
||||
Iterable<Person> aTeam = graphRepository.findAllByQuery( "name","A*");
|
||||
Iterable<Person> aTeam = graphRepository.findAllByQuery( "name","A*");
|
||||
|
||||
Iterable<Person> friends = personRepository.findFriends(dave);
|
||||
]]></programlisting>
|
||||
Iterable<Person> friends = personRepository.findFriends(dave);
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -1,93 +1,113 @@
|
||||
<?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>
|
||||
<title>Transactions in Spring Data Graph</title>
|
||||
<title>Transactions</title>
|
||||
<para>
|
||||
Neo4j is a transactional datastore which only allows modifications within transaction boundaries and fullfills
|
||||
the ACID properties. Reading from the store is also possible outside of transactions.
|
||||
Neo4j is a transactional database, only allowing modifications to be performed within transaction
|
||||
boundaries. Reading data does however not require transactions.
|
||||
</para>
|
||||
|
||||
<para>Spring Data Graph integrates with transaction managers configured using Spring. The simplest scenario of
|
||||
just running the graph database uses a SpringTransactionManager provided by the Neo4j kernel to be used
|
||||
with Spring's JtaTransactionManager.
|
||||
|
||||
Note: The explicit XML configuration given below is encoded in the <code>Neo4jConfiguration</code>
|
||||
configuration bean that uses Spring's @Configuration functioanlity. This simplifies the configuration.
|
||||
An example is shown further below.
|
||||
<para>
|
||||
Spring Data Graph integrates with transaction managers configured using Spring. The simplest
|
||||
scenario of just running the graph database uses a SpringTransactionManager provided by the
|
||||
Neo4j kernel to be used with Spring's JtaTransactionManager. That is, configuring Spring to
|
||||
use Neo4j's transaction manager.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<note>
|
||||
<para>
|
||||
The explicit XML configuration given below is encoded in the <code>Neo4jConfiguration</code>
|
||||
configuration bean that uses Spring's <code>@Configuration</code> feature. This greatly
|
||||
simplifies the configuration of Spring Data Graph.
|
||||
<!--An example is shown further below.-->
|
||||
</para>
|
||||
</note>
|
||||
<example>
|
||||
<title>Simple transaction manager configuration</title>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
|
||||
<property name="transactionManager">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
|
||||
<constructor-arg ref="graphDatabaseService"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="userTransaction">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
|
||||
<constructor-arg ref="graphDatabaseService"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="transactionManager">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
|
||||
<constructor-arg ref="graphDatabaseService"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="userTransaction">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
|
||||
<constructor-arg ref="graphDatabaseService"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||
]]></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
For scenarios running multiple transactional resources there are two options.
|
||||
First of all you can have Neo4j participate in the externally set up transaction manager using the new
|
||||
SpringProvider by enabling the configuration parameter for your graph database. Either via the spring config
|
||||
or the configuration file (neo4j.properties).
|
||||
For scenarios with multiple transactional resources there are two options. The first option
|
||||
is to have Neo4j participate in the externally configured transaction manager by using the
|
||||
Spring support in Neo4j by enabling the configuration parameter for your graph database.
|
||||
Neo4j will then use Spring's transaction manager instead of its own.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<example>
|
||||
<title>Neo4j Spring integration</title>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<context:annotation-config />
|
||||
<context:spring-configured/>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
|
||||
<property name="transactionManager">
|
||||
<bean id="jotm" class="org.springframework.data.graph.neo4j.transaction.JotmFactoryBean"/>
|
||||
</property>
|
||||
<property name="transactionManager">
|
||||
<bean id="jotm" class="org.springframework.data.graph.neo4j.transaction.JotmFactoryBean"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.neo4j.kernel.EmbeddedGraphDatabase" destroy-method="shutdown">
|
||||
<constructor-arg value="target/test-db"/>
|
||||
<constructor-arg>
|
||||
<map>
|
||||
<entry key="tx_manager_impl" value="spring-jta"/>
|
||||
</map>
|
||||
</constructor-arg>
|
||||
<constructor-arg value="target/test-db"/>
|
||||
<constructor-arg>
|
||||
<map>
|
||||
<entry key="tx_manager_impl" value="spring-jta"/>
|
||||
</map>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||
]]></programlisting>
|
||||
]]></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
You can configure a stock XA transaction manager to be used with Neo4j and the other resources (e.g. Atomikos,
|
||||
JOTM, App-Server-TM). For a bit less secure but fast 1 phase commit best effort, use the implementation coming
|
||||
with Spring Data Graph (<code>ChainedTransactionManager</code>). 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.
|
||||
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,
|
||||
use <code>ChainedTransactionManager</code>, which comes bundled with Spring Data Graph. 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.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<example>
|
||||
<title>ChainedTransactionManager example</title>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="jpaTransactionManager"
|
||||
class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
<bean id="jtaTransactionManager"
|
||||
class="org.springframework.transaction.jta.JtaTransactionManager">
|
||||
<property name="transactionManager">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
|
||||
<constructor-arg ref="graphDatabaseService" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="userTransaction">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
|
||||
<constructor-arg ref="graphDatabaseService" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.data.graph.neo4j.transaction.ChainedTransactionManager" >
|
||||
class="org.springframework.data.graph.neo4j.transaction.ChainedTransactionManager">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="jpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
<bean
|
||||
class="org.springframework.transaction.jta.JtaTransactionManager">
|
||||
<property name="transactionManager">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
|
||||
<constructor-arg ref="graphDatabaseService" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="userTransaction">
|
||||
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
|
||||
<constructor-arg ref="graphDatabaseService" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
<ref bean="jpaTransactionManager"/>
|
||||
<ref bean="jtaTransactionManager"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||
]]></programlisting>
|
||||
</example>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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:typerepresentationstrategy">
|
||||
<title>Storing type information in the graph</title>
|
||||
<title>Entity types stored</title>
|
||||
<para>
|
||||
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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="samples">
|
||||
<title>Samples</title>
|
||||
<title>Sample code</title>
|
||||
|
||||
<section id="samples_introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="setup">
|
||||
<title>Setup required for Spring Data Graph</title>
|
||||
<title>Environment setup</title>
|
||||
<para>To use Spring Data Graph in your application, some setup is required. For building the application the necessary Maven dependencies must be included and
|
||||
for the AspectJ weaving some extensions of the compile goal are necessary. This chapter also discusses the Spring configuration needed to set up
|
||||
Spring Data Graph. Examples for this setup can be found in the <ulink url="http://github.com/SpringSource/spring-data-graph-examples">Spring Data Graph examples</ulink>.
|
||||
|
||||
Reference in New Issue
Block a user