split annotations documentation, one for the node entities, one for relationships and relationship entities

This commit is contained in:
Michael Hunger
2011-04-04 18:56:27 +02:00
parent 9a863890e4
commit b29816de79
2 changed files with 228 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
<?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>Using annotations to define POJO Node Entities</title>
<para>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>
<para>
The <code>@NodeEntity</code> annotation is used to declare a POJO entity to be backed by a node in the
graph store. Simple fields on the entity are mapped by default to properties of the node. Object
references to other NodeEntities (whether single or Collection) are mapped via relationships. If
the annotation parameter <code>useShortNames</code> is set to false, the properties and relationship
names used will be prepended with the class name of the entity.
</para><para>
If the <code>partial</code>
parameter is set to true, this entity takes part in a cross-store setting /<xref linkend="cross-store"/>)
where only the specifically annotated parts of the entity not handled by JPA will be mapped to the graph store.
</para>
<para>Entity fields can be annotated with @GraphProperty, @RelatedTo, @RelatedToVia, @Indexed, @GraphId and
@GraphTraversal.
</para>
<example>
<title>Simple Node Entity</title>
<programlisting language="java"><![CDATA[
// simplest example
@NodeEntity
public class Movie {
String title;
}
]]></programlisting>
</example>
</section>
<section>
<title>@GraphProperty: Optional Annotation for Property Fields</title>
<para>It is not necessary to annotate fields as they are persisted by default; all fields that contain primitive
values are persisted directly to the graph. All fields
convertible to String using the Spring conversion services will be stored as a string.
(Spring Data Graph adds a custom conversion factory that comes with converters for Enums and Dates).
Transient fields are not persisted.
This annotation is mainly used for cross-store persistence.
</para>
</section>
<section>
<title>@Indexed: Making entities searchable by field value</title>
<para>The @Indexed annotation can be declared on fields that are intended to be indexed by the Neo4j
indexing facilities, triggered by value modification.
The resulting index can be used to later retrieve nodes or relationships that contain a certain property
value (for example a name). Often an index is used to establish the start node for a traversal.
Indexes are accessed by a <code>Repository</code> for a particular node or relationship entity, created via a
<code>DirectGraphRepositoryFactory</code>.
</para>
<para>
GraphDatabaseContext exposes the indexes for Nodes and Relationships via the <code>getIndex</code> method.
Index names default to the domain class
name, but can also be named (<code>indexName</code> attribute)individually to reflect domain concepts.
be named, for instance to keep separate domain concepts in separate indexes.
</para>
<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"/>.
</para>
</section>
<section>
<title>@GraphTraversal: fields providing direct access to traversal results</title>
<para>The @GraphTraversal annotation leverages the delegation infrastructure used by the Spring Data Graph
aspects. It provides dynamic fields which, when accessed, return an Iterable of NodeEntities that are
the result of a traversal starting at the current NodeEntity. The TraversalDescription used for this
is created by a TraversalDescriptionBuilder whose class is referred to by the <code>traversalBuilder</code>
attribute of the annotation. The class of the expected NodeEntities is provided with the
<code>elementClass</code> attribute.
<example>
<title>@GraphTraversal in a Node Entity</title>
<programlisting language="java"><![CDATA[
@NodeEntity
public class Group {
@GraphTraversal(traversalBuilder = PeopleTraversalBuilder.class,
elementClass = Person.class, params = "persons")
private Iterable<Person> people;
private static class PeopleTraversalBuilder implements FieldTraversalDescriptionBuilder {
@Override
public TraversalDescription build(NodeBacked start, Field field, String...params) {
return new TraversalDescriptionImpl()
.relationships(DynamicRelationshipType.withName(params[0]))
.filter(Traversal.returnAllButStartNode());
}
}
}
]]></programlisting>
</example>
</para>
</section>
</section>

View File

@@ -0,0 +1,129 @@
<?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>How to relate Node Entities using Relationships</title>
<para>As relationships are first level 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 also imply its direction).
They can have an arbitrary number of properties. Spring Data Graph has special support to represent Neo4j relationships
as Relationship Entities but this is not mandatory.
</para>
<section>
<title>@RelatedTo: Connecting NodeEntities</title>
<para>
Every attribute of a Node Entity that refers to one or more Node Entity represents relationships and
is handled by the field-aspects to be reflected in the graph.
</para>
<para>
Those can either be single relationships (1:1) or multiple relationships (1:N).
In most cases single relationships to other node entities don't have to be annotated, as Spring Data Graph
can extract all necessary information
from the field using reflection. In the case of multiple relationships, the <code>elementClass</code>
parameter of @RelatedTo must be specified because of type erasure. The <code>direction</code>
(default OUTGOING) and <code>type</code> (inferred from field name) parameters of the annotation are
optional.
</para>
<para>
Single Relationships to other node entities are created when setting the field (deleting previously set
relationships) and deleted when setting it to null.
</para>
<para>
References to a set of Node Entities are declared as fields with a <code>Set&lt;T&gt;</code> type, where T
is a concrete Node-Entity. @RelatedTo is used again to provide information about type-name, elementClass and
direction.
It is not necessary to initialize the set as it is managed by Spring Data Graph, representing the relationships
from (to) this entity with the given type. Adding and removing from the set is reflected on the graph.
</para>
<para>
Spring Data Graph also ensures that there is only one relationship of the given type between two
given entities.
</para>
<note>
By setting direction to BOTH, relationships are created in the outgoing direction, but when the 1:N field
is read, it will include relationships in both directions. A cardinality of M:N is not necessary because
relationships can be navigated in both directions.
</note>
<example>
<title>Node Entity with Relationships</title>
<programlisting language="java"><![CDATA[
@NodeEntity
public class Movie {
private Actor topActor;
}
@NodeEntity
public class Person {
@RelatedTo(type = "topActor", direction = Direction.INCOMING)
private Movie wasTopActorIn;
}
@NodeEntity
public class Actor {
@RelatedTo(type = "ACTS_IN", elementClass = Movie.class)
private Set<Movie> movies;
}
]]></programlisting>
</example>
<para>
Other means of handling relationships are the introduced <code>entity.getRelationshipTo(target,type)</code> and
<code>entity.relateTo(target,type)</code> methods that are available on each NodeEntity. Those methods create
and return Neo4j relationships. It is possible to remove relationships manually using
<code>entity.removeRelationshipTo(target,type)</code>. For creating and accessing relationship-entities,
their equivalents are available.
</para>
</section>
<section>
<title>@RelationshipEntity: Rich relationships</title>
<para>
To access the full data model of graph relationships, POJOs can also be annotated with
@RelationshipEntity. Relationship entities can not be instantiated directly but are rather accessed via
node entities, either by @RelatedToVia fields or by the introduced
<code>entity.relateTo(target,relationshipClass,type)</code> and
<code>entity.getRelationshipTo(target,relationshipClass,type)</code> methods
(<xref linkend="reference:programming-model:introduced-methods"/>).
</para><para>
Relationship entities may contain fields that are mapped to simple properties and two special fields that are
annotated with <code>@StartNode</code> and <code>@EndNode</code> which point to the start and end node entities respectively. These
fields are treated as read only fields.
</para>
<example>
<title>Relationship Entity</title>
<programlisting language="java"><![CDATA[
@RelationshipEntity
public class Role {
String title;
@StartNode private Actor actor;
@EndNode private Movie movie;
}
]]></programlisting>
</example> </section>
<section>
<title>@RelatedToVia: Connecting Node Entitites via Relationship Entities</title>
<para>
To provide easy programmatic access to the richer relationship entities of the data model, a different
annotation <code>@RelatedToVia</code> can be declared on fields of <code>Iterable</code>s of the relationship entity type.
These Iterables then provide read only access to instances of the entity that backs the relationship of this
relationship type. Those instances are initialized with the properties of the relationship and the start
and end node.
</para>
<example>
<title>Using Relationship Entities and @RelatedToVia</title>
<programlisting language="java"><![CDATA[
@NodeEntity
public class Actor {
@RelatedToVia(type = "ACTS_IN", elementClass = Role.class)
private Iterable<Role> roles;
public Role playedIn(Movie movie, String title) {
Role role=relateTo(movie,Role.class,"ACTS_IN");
role.setTitle(title);
return role;
}
}
]]></programlisting>
</example>
</section>
</section>