diff --git a/src/docbkx/reference/cross-store.xml b/src/docbkx/reference/cross-store.xml index fa7a37fa1..d0f00b230 100644 --- a/src/docbkx/reference/cross-store.xml +++ b/src/docbkx/reference/cross-store.xml @@ -1,142 +1,155 @@ - Cross-store persistence - 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. - - - This allows existing JPA-based applications to embrace NOSQL data stores to evolve certain parts of their model. - Possible use cases are adding social network or geospatial information to existing applications. - -
- Partial graph persistence + Cross-store persistence + + The Spring Data Graph project support cross-store persistence, 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. + + + This allows existing JPA-based applications to embrace NOSQL data stores for evolving certain parts + of their data model. Possible use cases include adding social networking or geospatial information to + existing applications. + +
+ Partial entities - Partial graph persistence is achieved by restricting the Spring Data Graph aspects to explicitly annotated parts of - the entity. Those fields will be made transient by the aspect so that JPA ignores them and won't try to persist those - attributes. + Partial graph persistence is achieved by restricting the Spring Data Graph aspects to manage only + explicitly annotated parts of the entity. Those fields will be made @Transient by the + aspect so that JPA ignores them. - A backing node in the graph store is only created when the entity has been assigned a JPA id. Only then will the connection between the - two stores be kept. Until the entity has been persisted, its state is just kept inside the POJO (detached state) and flushed to the - 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 - 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. + 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 persist(). - - 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 - the POJO and setting its id manually) to find the matching node using the index facilities and reconnect them. - - - Using those mechanisms and the Spring Data Graph aspects a single POJO can contain fields that are handled by JPA and other fields - (which might be relationships as well) that are handled by Spring Data Graph. - -
- @NodeEntity(partial = "true") - - When annotating an entity with partial true, Spring Data Graph assumes that this is a cross-store entity. So its only responsibility is for the fields - annotated with Spring Data Graph annotations. JPA should not take care of these fields (they should be annotated with @Transient). In this mode of - operation Spring Data Graph also handles the cross-store connection via the content of the JPA id field. - -
-
- @GraphProperty - - For common fields containing primitive or convertible values that wouldn't have to be annotated in exclusive Spring Data Graph operations this - explicit declaration is necessary to be sure that they are intended to be stored in the graph. These fields should then be made transient - so that JPA doesn't try to take care of them as well. - -
- - The following example is taken from the Spring Data Graph examples, - it is contained in the myrestaurant-social project. - - + The association between the two entities is maintained 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 + database. Given 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. The matching node + can then be found using the indexing facilities, and the two entities can be reassociated. + + + Using these mechanisms and the Spring Data Graph aspects, a single POJO can contain some fields + handled by JPA and others handles by Spring Data Graph. This also includes relationship fields persisted + in the graph database. + +
+
+ Cross-store annotations + + Cross-store persistence only requires the use of one additional annotation: @GraphProperty. + See below for details and an example. + +
+ @NodeEntity(partial = "true") + + When annotating an entity with partial = true, this marks it as a cross-store entity. + Spring Data Graph will thus only manage fields explicitly annotated with @GraphProperty. + +
+
+ @GraphProperty + + Fields of primitive or convertible types do not normally have to be annotated in order to be + persisted by Spring Data Graph. In cross-store mode, Spring Data Graph only + persists fields explicitly annotated with @GraphProperty. JPA will ignore these fields. + +
+ + The following example is taken from the + Spring Data Graph examples + myrestaurants-social project: + + + Cross-store node entity + friends; + @RelatedTo(type = "friends", elementClass = UserAccount.class) + Set friends; - @RelatedToVia(type = "recommends", elementClass = Recommendation.class) - Iterable recommendations; + @RelatedToVia(type = "recommends", elementClass = Recommendation.class) + Iterable recommendations; - @Temporal(TemporalType.TIMESTAMP) - @DateTimeFormat(style = "S-") - private Date birthDate; + @Temporal(TemporalType.TIMESTAMP) + @DateTimeFormat(style = "S-") + private Date birthDate; - @ManyToMany(cascade = CascadeType.ALL) - private Set favorites; + @ManyToMany(cascade = CascadeType.ALL) + private Set favorites; - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(name = "id") - private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; - @Transactional - public void knows(UserAccount friend) { - relateTo(friend, "friends"); - } + @Transactional + public void knows(UserAccount friend) { + relateTo(friend, "friends"); + } - @Transactional - public Recommendation rate(Restaurant restaurant, int stars, String comment) { - Recommendation recommendation = relateTo(restaurant, Recommendation.class, "recommends"); - recommendation.rate(stars, comment); - return recommendation; - } - public Iterable getRecommendations() { - return recommendations; - } - } + @Transactional + public Recommendation rate(Restaurant restaurant, int stars, String comment) { + Recommendation recommendation = relateTo(restaurant, Recommendation.class, "recommends"); + recommendation.rate(stars, comment); + return recommendation; + } + public Iterable getRecommendations() { + return recommendations; + } +} ]]> -
-
- Configuring cross-store persistence - - Configuring cross-store persistence is done similarly to the default Spring Data Graph operations. As soon as you refer - to an entityManagerFactory in the xml-namespace it is set up for cross-store persistence. - - +
+
+ Configuring cross-store persistence + + Configuring cross-store persistence is done similarly to the default Spring Data Graph configuration. + All you need to do is to specify an entityManagerFactory in the XML namespace + config element, and Spring Data Graph will configure itself for cross-store use. + + + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd + http://www.springframework.org/schema/data/graph + http://www.springframework.org/schema/data/graph/datagraph-1.0.xsd + "> - + + id="entityManagerFactory"> ]]> -
+