Edited relationships reference chapter.
This commit is contained in:
@@ -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:annotations">
|
||||
<title>Using annotations to define POJO Node Entities</title>
|
||||
<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.
|
||||
</para>
|
||||
|
||||
@@ -1,74 +1,84 @@
|
||||
<?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.
|
||||
<title>Relationships relate 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
|
||||
imply the direction of the relationship). Relationships can have an arbitrary number of properties.
|
||||
Spring Data Graph has special support to represent Neo4j relationships as entities too, but it is often
|
||||
not needed.
|
||||
</para>
|
||||
<section>
|
||||
<title>@RelatedTo: Connecting NodeEntities</title>
|
||||
<title>@NodeEntity</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.
|
||||
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>
|
||||
Every field of a node entity that references one or more other node entities is backed by relationships
|
||||
in the graph. These relationships are managed by Spring Data Graph automatically.
|
||||
</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.
|
||||
The simplest kind of relationship is a single field pointing to another node entity (1:1).
|
||||
In this case, the field does not have to be annotated at all, although the annotation may be
|
||||
used to control the direction and type of the relationship. When setting the field, a
|
||||
relationship is created. If the field is set to <code>null</code>, the relationship is removed.
|
||||
</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<T></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[
|
||||
|
||||
<example>
|
||||
<title>Single relationship field</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;
|
||||
private Actor mostPaidActor;
|
||||
}
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</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.
|
||||
It is also possible to have fields that reference a set of node entities (1:N). These fields come in
|
||||
two forms, modifiable or read-only. Modifiable fields are of the type <code>java.util.Set<T></code>,
|
||||
and read-only fields are <code>java.lang.Iterable<T></code>, where T is a @NodeEntity-annotated
|
||||
class. The Java implementation of generics uses type erasure, meaning that the type parameters are
|
||||
typically not available at runtime. Therefore, the <code>elementClass</code> attribute must be
|
||||
specified on the annotation, which must always be present for 1:N fields.
|
||||
</para>
|
||||
<example>
|
||||
<title>Node entity with relationships</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
@NodeEntity
|
||||
public class Actor {
|
||||
@RelatedTo(type = "mostPaidActor", direction = Direction.INCOMING, elementClass = Movie.class)
|
||||
private Set<Movie> mostPaidIn;
|
||||
|
||||
@RelatedTo(type = "ACTS_IN", elementClass = Movie.class)
|
||||
private Set<Movie> movies;
|
||||
}
|
||||
]]></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
Fields referencing other entities should not be manually initialized, as they are managed by
|
||||
Spring Data Graph under the hood. 1:N fields can be accessed immediately, and Spring Data Graph
|
||||
will provide a java.util.Set representing the relationships. If the returned set is modified,
|
||||
the changes are reflected in the graph. Spring Data Graph also ensures that there is only one
|
||||
relationship of a given type between any 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>
|
||||
<para>
|
||||
The relationships can also be accessed by using the aspect-introduced methods
|
||||
<code>entity.getRelationshipTo(target, type)</code> and
|
||||
<code>entity.relateTo(target, type)</code> available on each NodeEntity.
|
||||
These methods find and create Neo4j relationships. It is also possible to manually remove
|
||||
relationships by using <code>entity.removeRelationshipTo(target, type)</code>.
|
||||
Using these methods is rarely necessary though.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -76,54 +86,71 @@ private Set<Movie> movies;
|
||||
<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.
|
||||
<code>@RelationshipEntity</code>, making them relationship entities. Just as node entities represent
|
||||
nodes in the graph, relationship entities represent relationships. As described above,
|
||||
fields annotated with <code>@RelatedTo</code> provide a way to link node entities together
|
||||
via relationships, but it provides no way of accessing the relationships themselves.
|
||||
</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.
|
||||
Relationship entities cannot be instantiated directly but are rather created via
|
||||
node entities, either by @RelatedToVia-annotated fields
|
||||
(see <xref linkend="reference:programming_model:relationships:relatedtovia"/>),
|
||||
or by the introduced
|
||||
<code>entity.relateTo(target, relationshipClass, type)</code> and
|
||||
<code>entity.getRelationshipTo(target, relationshipClass, type)</code> methods
|
||||
(see <xref linkend="reference:programming-model:introduced-methods"/>).
|
||||
</para>
|
||||
<example>
|
||||
<title>Using Relationship Entities and @RelatedToVia</title>
|
||||
<programlisting language="java"><![CDATA[
|
||||
<para>
|
||||
Fields in relationship entities are, similarly to node entities, persisted as properties on
|
||||
the relationship. For accessing the two endpoints of the relationship, two special annotations
|
||||
are available: <code>@StartNode</code> and <code>@EndNode</code>. A field annotated with
|
||||
one of these annotations will provide read-only access to the corresponding endpoint, depending
|
||||
on the chosen annotation.
|
||||
</para>
|
||||
<example>
|
||||
<title>Relationship entity</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;
|
||||
public Role playedIn(Movie movie, String title) {
|
||||
return relatedTo(movie, Role.class, "ACTS_IN");
|
||||
}
|
||||
}
|
||||
|
||||
@RelationshipEntity
|
||||
public class Role {
|
||||
String title;
|
||||
|
||||
@StartNode private Actor actor;
|
||||
@EndNode private Movie movie;
|
||||
}
|
||||
]]></programlisting>
|
||||
|
||||
</example>
|
||||
</section>
|
||||
<section id="reference:programming_model:relationships:relatedtovia">
|
||||
<title>@RelatedToVia: Accessing relationship entities</title>
|
||||
<para>
|
||||
To provide easy programmatic access to the richer relationship entities of the data model,
|
||||
the annotation <code>@RelatedToVia</code> can be added on fields of type
|
||||
<code>java.lang.Iterable<T></code>, where T is a <code>@RelationshipEntity</code>-annotated
|
||||
class. These fields provide read-only access to relationship entities.
|
||||
</para>
|
||||
<example>
|
||||
<title>Accessing relationship entities using @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>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
Reference in New Issue
Block a user