Aparna Greenscapes Kompally Hyderabad E - Brochure.pdf
3/15 - Intro to Spring Data Neo4j
1. Webinar
Introduction to
Spring Data Neo4j 2.0
Michael Hunger, Neo Technology
Thursday, March 15, 12
2. Me & You ?
๏ Me: Michael Hunger, Neo Technology
• passionate software developer / Neo4j German Division
• Spring Data Neo4j Project Lead
• Neo4j Cloud Hosting
• michael.hunger@neotechnology.com / @mesirii
๏ You:
• Java & Spring !
• Enterprise ?
• Rich Domain ?
• NOSQL ?
Thursday, March 15, 12
3. About the Webinar
๏ Covers Spring Data Neo4j only
๏ too much content anyway
๏ so it will be just a whirlwind tour
๏ no detailed introductions to NOSQL and Neo4j in particular
๏ for those go to http://neo4j.org
๏ Q&A at the end
๏ all your questions will be answered in a follow up blog post,
don‘t hesitate to ask
Thursday, March 15, 12
4. What‘s up?
๏ Spring Data overview
๏ Networks are everywhere
๏ Neo4j introduction
๏ Spring Data Neo4j introduction
4
Thursday, March 15, 12
7. What is NOSQL?
It’s not “No to SQL”
Thursday, March 15, 12
8. What is NOSQL?
It’s not “No to SQL”
It’s not “Never SQL”
Thursday, March 15, 12
9. What is NOSQL?
It’s not “No to SQL”
It’s not “Never SQL”
It’s “Not Only SQL”
Thursday, March 15, 12
10. What is NOSQL?
It’s not “No to SQL”
It’s not “Never SQL”
It’s “Not Only SQL”
NOSQL no-seek-wool n. Describes ongoing
trend where developers increasingly opt for
non-relational databases to help solve their
problems, in an effort to use the right tool for
the right job.
Thursday, March 15, 12
11. NOSQL categories
We see four main categories in the NOSQL space:
Thursday, March 15, 12
12. NOSQL categories
We see four main categories in the NOSQL space:
Key-Value
•Redis
•Riak
•Voldemort
Thursday, March 15, 12
13. NOSQL categories
We see four main categories in the NOSQL space:
Column-family/
Key-Value
BigTable
•Redis
•Riak •Cassandra
•Voldemort •HBase
Thursday, March 15, 12
14. NOSQL categories
We see four main categories in the NOSQL space:
Column-family/
Key-Value
BigTable
•Redis
•Riak •Cassandra
•Voldemort •HBase
Document
•MongoDB
•CouchDB
Thursday, March 15, 12
15. NOSQL categories
We see four main categories in the NOSQL space:
Column-family/
Key-Value
BigTable
•Redis
•Riak •Cassandra
•Voldemort •HBase
Document Graph
•Neo4j
•MongoDB
•InfiniteGraph
•CouchDB
•OrientDB
•DEX
Thursday, March 15, 12
16. Scaling to size vs. Scaling to complexity
Size
Key-Value stores
Bigtable clones
Document databases
Graph databases
Complexity
8
Thursday, March 15, 12
17. Scaling to size vs. Scaling to complexity
Size
Key-Value stores
Bigtable clones
Document databases
Graph databases
Billions of nodes
and relationships
Complexity
8
Thursday, March 15, 12
18. Scaling to size vs. Scaling to complexity
Size
Key-Value stores
Bigtable clones
Document databases
Graph databases
Billions of nodes
and relationships
> 90% of use cases
Complexity
8
Thursday, March 15, 12
19. Why NOSQL now?
We have observed four trends since the 90‘s:
๏ Trend 1: Size of data is growing
๏ Trend 2: Data is increasingly connected
๏ Trend 3: Data is increasingly semi-structured
๏ Trend 4: Change in architecture
Thursday, March 15, 12
20. What is Spring Data?
๏ VMWare/SpringSource initiative to give Spring developers easy
access to the emerging world of NOSQL, including:
• Non-relational databases
• Grails NOSQL support
• Cross-store persistence
• Object Persistence Mapping Infrastructure
• Generic Repository Infrastructure
• upcoming Spring Roo add-ons
10
Thursday, March 15, 12
21. Spring Data projects
๏ Code is in SpringSource git repository:
• http://springsource.org/spring-data
• https://github.com/SpringSource/spring-data-*
๏ Includes:
• data-commons
• spring-data-graph-neo4j
• spring-data-{redis,riak}
• spring-data-mongo
• spring-data-jdbc
• spring-data-jpa
Thursday, March 15, 12
22. Spring Data Neo4j
๏ Focus on Spring Data Neo4j
๏ VMWare is collaborating with Neo Technology, the company behind
the Neo4j graph database.
๏ Improved programming model: Annotation-based
programming model for applications with rich domain models
๏ Cross-store persistence: Extend existing JPA application with
NOSQL persistence
๏ Spring Roo support: Add graph persistence with Roo add-on
Thursday, March 15, 12
23. Graphs are
everywhere
13
Thursday, March 15, 12
24. Even in the Matrix
- everything is a graph
Google Image Search: „graph OR network“
14
Thursday, March 15, 12
25. Graphs Everywhere
๏ Relationships in
• Politics, Economics, History, Science,Transportation
๏ Biology, Chemistry, Physics, Sociology
• Body, Ecosphere, Reaction, Interactions
๏ Internet / IT
• Hardware, Software, Interaction
๏ Social Networks
• Family, Friends
• Work, Communities
• Neighbours, Cities, Society
Thursday, March 15, 12
15
26. Good Relationships
๏ World is rich, messy and related data
๏ Relationships are as least as important as the things they connect
๏ Graphs = Whole > Sum of all parts
๏ Complex interactions
๏ Always changing, change of structures as well
๏ Graph => Relationships are part of the data
๏ RDBMS => Relationships part of the fixed schema
16
Thursday, March 15, 12
27. Questions and Answers
๏ Complex Questions
๏ Answers lie between the lines (things)
๏ Locality of the information
๏ Global searches / operations very expensive
๏ Constant query time, regardless of data volume
17
Thursday, March 15, 12
28. Categories ?
๏ Categories == Classes, Trees ?
๏ What if more than one category fits?
๏ Tags
๏ Categories via relationships like „IS_A“
๏ Any number, easy to change
๏ „Virtual“ Relationships - Traversals
๏ Category dynamically derived from queries
18
Thursday, March 15, 12
38. For example
name: Oliver
Thursday, March 15, 12
39. For example
name: Oliver name: Michael
Thursday, March 15, 12
40. For example
WORKS_WITH
project: spring-data
name: Oliver name: Michael
Thursday, March 15, 12
41. For example
WORKS_WITH
project: spring-data
name: Oliver name: Michael
EM
PL
LIVES_IN
OY
E
D_
BY
city: Dresden
company: VMware country: DE
Thursday, March 15, 12
42. For example
name: Rod
KN
S OW
OW S
KN
WORKS_WITH
project: spring-data
name: Oliver name: Michael
EM
PL
LIVES_IN
OY
E
D_
BY
city: Dresden
company: VMware country: DE
Thursday, March 15, 12
43. For example
name: Rod
KN
S OW
OW S
KN
WORKS_WITH
project: spring-data
name: Oliver name: Michael
EM
PL
LIVES_IN
S
OY
LIKE
E
D_
BY
city: Dresden
food: Chinese
company: VMware country: DE
Thursday, March 15, 12
44. Facts about Neo4j
•Written in Java
•Embeddable or standalone Server
•Schema-free - perfect for rich domains
•Fully transactional (ACID)
•Persistent to custom on-disk file structure
•Traversal speeds of 1,000,000+ hops per second
•Integrated indexing
•Plenthora of language bindings
•24/7 production since 2003
Thursday, March 15, 12
45. Show me some code, please
GraphDatabaseService graphDb =
new EmbeddedGraphDatabase(“var/neo4j”);
Node david = graphDb.createNode();
Node andreas = graphDb.createNode();
david.setProperty(“name”, “David Montag”);
andreas.setProperty(“name”, “Andreas Kollegger”);
Relationship presentedWith = david.createRelationshipTo(
andreas, PresentationTypes.PRESENTED_WITH);
presentedWith.setProperty(“date”, System.currentTimeMillis());
Thursday, March 15, 12
46. Show me some code, please
GraphDatabaseService graphDb =
new EmbeddedGraphDatabase(“var/neo4j”);
Transaction tx = graphDb.beginTx();
try {
Node david = graphDb.createNode();
Node andreas = graphDb.createNode();
david.setProperty(“name”, “David Montag”);
andreas.setProperty(“name”, “Andreas Kollegger”);
Relationship presentedWith = david.createRelationshipTo(
andreas, PresentationTypes.PRESENTED_WITH);
presentedWith.setProperty(“date”, System.currentTimeMillis());
tx.success();
} finally {
tx.finish();
}
Thursday, March 15, 12
48. Traversal framework
Example: a dependency graph
A
B
D
C
Thursday, March 15, 12
49. Traversal framework
Example: a dependency graph
Query: Find all dependencies of A, transitively
A
B
D
C
Thursday, March 15, 12
50. Traversal framework
Example: a dependency graph
Query: Find all dependencies of A, transitively
A
B
D
C
Thursday, March 15, 12
51. Traversal framework
Example: a dependency graph
Query: Find all dependencies of A, transitively
A
B
D
C
Thursday, March 15, 12
52. Traversal framework
Example: a dependency graph
Query: Find all dependencies of A, transitively
A
B
D
C
Thursday, March 15, 12
53. Traversal framework
Example: a dependency graph
Query: Find all dependencies of A, transitively A
B
D
C
TraversalDescription desc = Traversal.description()
.relationships(ExampleTypes.DEPENDS_ON, Direction.OUTGOING);
Node a = ...;
for (Node dependency : desc.traverse(a).nodes()) {
print(dependency);
}
Thursday, March 15, 12
54. So how do I find a node
to traverse from?
?
Thursday, March 15, 12
55. So how do I find a node
to traverse from?
g!
in
ex
i nd
i ng
us
B y ?
Thursday, March 15, 12
56. So how do I find a node
to traverse from?
g!
in
ex
i nd
i ng
us
B y name: David
?
Thursday, March 15, 12
57. So how do I find a node
to traverse from?
g!
in
ex
i nd
i ng
us
B y name: David
?
David
Thursday, March 15, 12
58. So how do I find a node
to traverse from?
g! Andreas
in
ex
i nd Michael
i ng
us
B y name: David
?
David
Ed
Allison
Thursday, March 15, 12
59. Cypher Query Language
๏ Declarative query language
• Describe what you want, not how
• Based on pattern matching
๏ Examples:
START david=node:people(name=”David M”) # index lookup
MATCH david-[:knows]-friends-[:knows]-new_friends
WHERE new_friends.age > 18
RETURN new_friends
START user=node(5, 15, 26, 28) # node IDs
MATCH user--friend
RETURN user, COUNT(friend), SUM(friend.money)
26
Thursday, March 15, 12
60. Beyond basics
๏ Traversal API / DSL
• Express powerful Graph Traversals succinctly
๏ Graph algorithm library
• Cheapest path (Dijkstra, A*)
• Shortest path
• Simple paths
• All paths
๏ REST API access to Neo4j Standalone Server
๏ High availability and online backups
27
Thursday, March 15, 12
62. Spring Framework Conveniences
๏ default enterprise development framework
๏ future Java Cloud stack
๏ POJO centric application design
๏ made AspectJ aspects socially acceptable (tx-config, @Configurable)
๏ Template programming model
๏ Inversion of Control / Dependency Injection
๏ Spring Java Config, configuration XML-namespaces
๏ lots of powerful libraries and library abstractions
๏ existing, well-known persistence framework for JDBC
๏ Spring Data project
Thursday, March 15, 12
63. Programming model overview
๏ SDN is the brain child of Rod Johnson and Emil Eifrém
• Wrote functional initial prototype
• Developed by Neo Technology and SpringSource teams
๏ Uses annotations to define graph entities
๏ Entity state backed by graph database
๏ Two modes of Object Graph Mapping
• POJO Graph Mapping
• seamless AspectJ backed Object Graph Mapping
๏ Spring Roo add-on available
Thursday, March 15, 12
64. Spring Data Neo4j features
๏ Annotation-based programming model
๏ Spring Data Commons Repository support
๏ Neo4j Query (Cypher, Gremlin) and Traversal support
• on dynamic fields and via repository methods
๏ Neo4j indexing support (includes fulltext and numeric range queries)
๏ Entity types stored in the graph database as well
๏ Dynamic type projection (duck typing)
๏ Cross-store support for partial JPA / graph entities
๏ Support for JSR-303 (bean validation)
๏ Support for the Neo4j Server (remote server and in server extension)
๏ Neo4jTemplate with exception translation, optional transaction management and
more
31
Thursday, March 15, 12
65. Classic Neo4j domain class
public class Actor {
private final Node underlyingNode;
Actor( final Node node ) {
underlyingNode = node;
}
public Node getUnderlyingNode() {
return underlyingNode;
}
public final String getName() {
return (String) underlyingNode.getProperty( “name” );
}
public void setName( final String name ) {
underlyingNode.setProperty( “name”, name );
}
}
Thursday, March 15, 12
66. Spring Data Neo4j domain class
@NodeEntity
public class Actor {
@Indexed
private String name;
}
Thursday, March 15, 12
67. What about relationships
@NodeEntity
class Actor {
...
public Iterable
<Movie> getMovi
final List<Movi es() {
e> movies = new
for ( Relations LinkedList<Movi
hip rel : under e>();
RelTypes.ACTS_I lyingNode.getRe
N, Direction.OU lationships(
movies.add( new TGOING ) ) {
Movie( rel.getE
}
return movies;
ndNode() ) );
Old
}
class)
@RelatedTo(type="ACTS_ IN", elementClass = Movie.
;
private Set<Movie> movies
public Iterable<Movie> ge
tMovies() {
New
return movies;
}
Thursday, March 15, 12
69. Defining entity classes
• @NodeEntity
• Represents a node in the graph
• Fields saved as properties on node
• References stored as relationships between nodes
• Instantiated using Java ‘new’ keyword, like any POJO
• Also returned by lookup mechanisms
• Type information stored in the graph
Thursday, March 15, 12
71. Defining entity classes
• @RelationshipEntity
• Represents a relationship in the graph
• Fields saved as properties on relationship
• Special fields for start- and end-nodes
• Only returned by lookup methods
Thursday, March 15, 12
72. Fields in node entities (@NodeEntity)
• Primitive types and strings are directly persisted
• For all other types, Spring conversion support can be used
• Enum and Date conversion is provided out-of-the-box
• Transient fields not persisted
@NodeEntity
public class Actor {
private String name;
private int age;
private HairColor hairColor;
private transient String nickname;
}
37
Thursday, March 15, 12
73. Fields in node entities (@NodeEntity)
• Fields of types that represent a node (@NodeEntity)
38
Thursday, March 15, 12
74. Fields in node entities (@NodeEntity)
• Fields of types that represent a node (@NodeEntity)
@NodeEntity
public class Movie {}
@NodeEntity
public class Person {
private Movie favoriteMovie;
}
38
Thursday, March 15, 12
75. Fields in node entities (@NodeEntity)
• Fields of types that represent a node (@NodeEntity)
@NodeEntity
public class Movie {}
@NodeEntity
public class Person {
private Movie favoriteMovie;
}
@NodeEntity
public class Movie {
private Actor topActor;
}
@NodeEntity
public class Actor {
// Mirrors topActor in Movie
@RelatedTo(type = ”topActor”, direction = Direction.INCOMING)
private Movie wasTopActorIn;
}
38
Thursday, March 15, 12
76. Fields in node entities (@NodeEntity)
• Fields of collections of node entities: @RelatedTo
@NodeEntity
public class Movie {}
@NodeEntity
public class Actor {
@RelatedTo(type = “ACTS_IN”)
private Set<Movie> movies;
}
39
Thursday, March 15, 12
77. Fields in node entities (@NodeEntity)
๏ Fields of collections of relationship entities: @RelatedToVia
@RelationshipEntity
public class Role {
@StartNode private Actor actor;
@EndNode private Movie movie;
private String roleName;
}
@NodeEntity
public class Actor {
@RelatedToVia(type = “ACTS_IN”)
private Iterable<Role> roles;
}
๏ Read only view of relationship entities 40
Thursday, March 15, 12
78. Fields in relationship entities
(@RelationshipEntity)
• Primitive and convertible types work just the same
• @StartNode and @EndNode provide access to the start and
end node entities for the relationship entity
@RelationshipEntity
public class Role {
@StartNode private Actor actor;
@EndNode private Movie movie;
private String title;
}
Thursday, March 15, 12
79. Indexing
By annotating an entity field with @Indexed it becomes searchable:
@NodeEntity
public class Actor {
@Indexed private String name;
@Indexed private HairColor hairColor;
It can then be looked up:
GraphRepository<Actor> actorRepo =
template.repositoryFor(Actor.class);
Actor kevin =
actorRepo.findByPropertyValue(“name”, “Kevin Bacon”);
Iterable<Actor> allBlondActors =
actorRepo.findAllByPropertyValue(“hairColor”, “blond”);
Thursday, March 15, 12
80. Indexing
@NodeEntity
public class Actor {
@Indexed(type = FULLTEXT)
private String name;
๏ Index name defaults to domain class name
๏ Index key defaults to field name
๏ Fulltext and spatial index types
๏ Repository query methods for any Lucene query, including ranges:
Iterable<Actor> allKevinsOlderThan32 =
actorRepo.findAllByQuery(“name:Kevin* AND age>32”);
Iterable<Actor> youngActors =
actorRepo.findAllByRange(“age”, 3, 18);
Thursday, March 15, 12
81. Traversal
@NodeEntity
public class Actor {
@GraphTraversal(
traversalBuilder = CoactorsTraversalDescriptionBuilder.class)
private Iterable<Actor> coactors;
}
public class CoactorsTraversalDescriptionBuilder implements
FieldTraversalDescriptionBuilder {
public TraversalDescription build(...) {
return Traversal.description()
.evaluator(Evaluators.atDepth(2))
.relationships(RelTypes.ACTS_IN);
}
}
Example for dynamic field computation
44
Thursday, March 15, 12
82. Cypher query language
@NodeEntity
public class Actor {
@Query(“START actor=node({self}) ” +
“MATCH actor-[:ACTS_IN]->movie<-[:ACTS_IN]-coactor ” +
“RETURN coactor”)
private Iterable<Actor> coactors;
}
@NodeEntity
public class User {
@Query(“START actor=node({self}) ” +
“MATCH actor-[:ACTS_IN]->movie<-[:ACTS_IN]-coactor ” +
“RETURN movie.title, coactor.name”)
private List<Map<String, Object>> movieCoactorPairs;
}
45
Thursday, March 15, 12
83. POJO-Mapping
๏ Based on Spring-Data-Commons infrastructure
• Extract Mapping Meta Information
• Entity-Converter for Object-Graph-Mapping
‣Type-resolution
‣Entity construction
‣Transfer properties
‣Load Cache
‣Load Policies + recurse for eagerly fetched relationships
• Neo4j-Template for Graph-Interaction
46
Thursday, March 15, 12
84. AspectJ
๏ Introduces interface to entities:
• NodeBacked into @NodeEntity classes
• RelationshipBacked into @RelationshipEntity classes
๏ NodeBacked introduces methods such as:
• relateTo
• findByQuery
• findAllByTraversal
• ...
๏ going to be pulled out in separate Active-Record-Mixin
47
Thursday, March 15, 12
85. AspectJ - Tooling
๏ IDE‘s
• latest versions of STS / Eclipse with current AJDT plugin
• IntelliJ IDEA 10.5 compile + run, some editor quirks
‣full AspectJ support in IDEA 11
๏ Build Systems
• Maven
• Gradle
• Ant / Ivy
• ...
48
Thursday, March 15, 12
86. AspectJ - NodeBacked.relateTo
<T extends RelationshipBacked> T NodeBacked.relateTo(
NodeBacked node,
Class<T> relationshipEntityType,
String relationshipType
);
usage:
@NodeEntity
public class Actor {
public Role actsIn(Movie movie, String roleName) {
Role role = relateTo(movie, Role.class, “ACTS_IN”);
role.setName(roleName);
return role;
}
}
49
Thursday, March 15, 12
87. Interface based Repositories
๏ based on Repository infrastructure in Spring Data Commons
๏ just define the interface and the namespace configuration
๏ provide out-of-the-box support for
• CRUD-Operations
• Index-Lookups
• Traversal-Execution
• Annotated Graph-Queries (Cypher, Gremlin)
• Derived Queries
• Spatial Queries
๏ extensible via custom methods with provided implementations
50
Thursday, March 15, 12
88. Repositories
interface MovieRepository extends GraphRepository<Movie> {
Movie findById(String id);
Page<Movie> findByTitle(String title, Pageable page);
}
<neo4j:repositories base-package=“com.example.repositories„/>
@Controller
public class MovieController {
@Autowired MovieRepository moviesRepository;
@RequestMapping(value = "/movies/{movieId}",...)
public String show(Model model, @PathVariable String movieId) {
Movie movie = moviesRepository.findByPropertyValue("id", movieId);
Movie movie = moviesRepository.findById(movieId);
model.addAttribute("movie", movie);
return "/movies/show";
}}
51
Thursday, March 15, 12
89. Repository-Query-Support
interface MovieRepository extends GraphRepository<Movie> {
@Query("start m=({movie}) match m-[ACTS_IN]-actor return actor")
List<Actor> getActorsCypher(@Param("movie") Movie m);
@Query("start movie =({0}) match (movie)<-[role:ACTS_IN]-(actor)
return actor.name, role.title")
Iterable<Map<String,Object>> getCast(Movie m);
@Query(value = "g.v(movie).out('ACTS_IN')", type = QueryType.Gremlin)
Set<Person> getActorsGremlin(@Param("movie") Movie m);
Page<Person> findByTitleAndActorsName(String title, String name,
Pageable page);
}
52
Thursday, March 15, 12
90. Neo4j-Template (I)
๏ well known Spring Template Pattern
๏ Resource / Transaction Management
๏ Convenience Methods
๏ Nodes and Entities handling & conversion
๏ Fluent Query Result Handling
๏ Works also via REST with Neo4j-Server
๏ Exception Translation
53
Thursday, March 15, 12
91. Neo4j-Template (II)
template.lookup("node", "name", "David")
.to(String.class, new PropertyContainerNameConverter()).single()
template.traverse(node, traversal)
.to(Integer.class,new ResultConverter<Path,Integer>() {
public Integer convert(Path path, Class<String> type) {
return path.length();
}})
template.query("start movie=(Movies,title, {m}) match movie-->actor return actor",
map("m","Matrix")).to(Actor.class)
template.execute("g.v(ref).outE", map("ref",0)).to(Relationship.class)
54
Thursday, March 15, 12
92. REST-Client-Support
<bean id="restGraphDatabaseService"
class="org.sf.data.neo4j.rest.SpringRestGraphDatabase">
<constructor-arg value="http://localhost:7473/db/data" />
</bean>
<datagraph:config graphDatabaseService="restGraphDatabaseService"/>
๏ drop-in replacement for the embedded GraphDatabase
๏ works transparently with POJO-Entity-Mapping and
Neo4j-Template
55
Thursday, March 15, 12
93. REST-Server-Support
public class HelloWorldInitializer extends SpringPluginInitializer {
public HelloWorldInitializer() {
super(new String[]{"spring/helloWorldServer-Context.xml"},
Pair.of("worldRepository", WorldRepository.class),
Pair.of("graphRepositoryFactory",
GraphRepositoryFactory.class));
}
}
๏ integrate Spring Data Neo4j config with already running
Graph-Database in Neo4j-Server
๏ expose Spring Beans as Jersey Injectables
56
Thursday, March 15, 12
95. A scenario...
You have a traditional web app using JPA to persist data to a relational
database
Thursday, March 15, 12
96. Option C: Introducing cross-store
persistence
๏ JPA data and NOSQL data can share a data model
๏ Could be the entire entity, or some fields of an entity
๏ We call this cross-store persistence
• One transaction managerdatabase the NOSQL database
with the JPA relational
to coordinate
• AspectJ support to manage the NOSQL entities and fields
Thursday, March 15, 12
97. The JPA data model
Restaurant UserAccount
@Entity @Entity
public class Restaurant { @Table(name = "user_account")
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
private Set<Restaurant> favorites;
Thursday, March 15, 12
98. Adding to the data model
Restaurant UserAccount
@Entity @Entity
@NodeEntity(partial = true) @Table(name = "user_account")
public class Restaurant { @NodeEntity(partial = true)
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
Recommendation private Set<Restaurant> favorites;
@RelationshipEntity @GraphProperty
public class Recommendation { String nickname;
@StartNode @RelatedTo(type = "friends",
private UserAccount user; elementClass = UserAccount.class)
@EndNode Set<UserAccount> friends;
private Restaurant restaurant; @RelatedToVia(type = "recommends",
private int stars; elementClass = Recommendation.class)
private String comment; Iterable<Recommendation> recommendations;
Thursday, March 15, 12
99. Adding to the data model
Restaurant UserAccount
@Entity @Entity
@NodeEntity(partial = true) @Table(name = "user_account")
public class Restaurant { @NodeEntity(partial = true)
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
Recommendation private Set<Restaurant> favorites;
@RelationshipEntity @GraphProperty
public class Recommendation { String nickname;
@StartNode @RelatedTo(type = "friends",
private UserAccount user; elementClass = UserAccount.class)
@EndNode Set<UserAccount> friends;
private Restaurant restaurant; @RelatedToVia(type = "recommends",
private int stars; elementClass = Recommendation.class)
private String comment; Iterable<Recommendation> recommendations;
Thursday, March 15, 12
100. Adding to the data model
Restaurant UserAccount
@Entity @Entity
@NodeEntity(partial = true) @Table(name = "user_account")
public class Restaurant { @NodeEntity(partial = true)
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
Recommendation private Set<Restaurant> favorites;
@RelationshipEntity @GraphProperty
public class Recommendation { String nickname;
@StartNode @RelatedTo(type = "friends",
private UserAccount user; elementClass = UserAccount.class)
@EndNode Set<UserAccount> friends;
private Restaurant restaurant; @RelatedToVia(type = "recommends",
private int stars; elementClass = Recommendation.class)
private String comment; Iterable<Recommendation> recommendations;
Thursday, March 15, 12
101. Adding to the data model
Restaurant UserAccount
@Entity @Entity
@NodeEntity(partial = true) @Table(name = "user_account")
public class Restaurant { @NodeEntity(partial = true)
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
Recommendation private Set<Restaurant> favorites;
@RelationshipEntity @GraphProperty
public class Recommendation { String nickname;
@StartNode @RelatedTo(type = "friends",
private UserAccount user; elementClass = UserAccount.class)
@EndNode Set<UserAccount> friends;
private Restaurant restaurant; @RelatedToVia(type = "recommends",
private int stars; elementClass = Recommendation.class)
private String comment; Iterable<Recommendation> recommendations;
Thursday, March 15, 12
102. Adding to the data model
Restaurant UserAccount
@Entity @Entity
@NodeEntity(partial = true) @Table(name = "user_account")
public class Restaurant { @NodeEntity(partial = true)
@Id @GeneratedValue public class UserAccount {
private Long id; @Id @GeneratedValue
private String name; private Long id;
private String city; private String userName;
private String state; private String firstName;
private String zipCode; private String lastName;
@Temporal(TemporalType.TIMESTAMP)
private Date birthDate;
@ManyToMany(cascade = CascadeType.ALL)
Recommendation private Set<Restaurant> favorites;
@RelationshipEntity @GraphProperty
public class Recommendation { String nickname;
@StartNode @RelatedTo(type = "friends",
private UserAccount user; elementClass = UserAccount.class)
@EndNode Set<UserAccount> friends;
private Restaurant restaurant; @RelatedToVia(type = "recommends",
private int stars; elementClass = Recommendation.class)
private String comment; Iterable<Recommendation> recommendations;
Thursday, March 15, 12
103. Spring Data Neo4j Roo add-on
๏ Roo adding support for non-JPA
persistence providers
๏ Spring Data Neo4j was the first
NOSQL persistence Roo
Add-On
๏ See the chapter on Spring Data
Neo4j in the latest O’Reilly
Roo book, Getting Started with
Roo.
62
Thursday, March 15, 12
104. Spring Data Neo4j Roo add-on
roo> project --topLevelPackage org.neo4j.imdb
roo> graph setup --provider NEO4J --databaseLocation target/imdb
roo> graph entity --class ~.model.Movie
roo> field string title
roo> field number --fieldName year --type java.lang.Integer --permitReservedWords --primitive
roo> graph entity --class ~.model.Actor
roo> field string name
roo> graph relationship --to Movie --from Actor --fieldName movies --type ACTS_IN
--cardinality ONE_TO_MANY
roo> graph relationship --via ~.model.Role --to Movie --from Actor --fieldName roles
--type ACTS_IN --cardinality ONE_TO_MANY
roo> graph relationship --from Movie --to Actor --type ACTS_IN --fieldName actors
--direction INCOMING --cardinality MANY_TO_ONE
roo> field string --fieldName title --class ~.model.Role
roo> controller scaffold --class ~.web.ActorController --entity ~.model.Actor
roo> controller scaffold --class ~.web.MovieController --entity ~.model.Movie
63
Thursday, March 15, 12
105. Spring Data Neo4j Guidebook
“Good Relationships”
“I’m excited about Spring Data Neo4j.... Spring Data Neo4j makes working
with Neo4j amazingly easy, and therefore has the potential to make you
more successful as a developer.”
Rod Johnson, founder of Spring
๏ Spring Data Neo4j comes with a great Guide Book, featuring:
• Forewords by Rod Johnson and Emil Eifrem
• An easy to read, narrative tutorial walkthrough for cineasts.net
• A comprehensive reference for all the details
• Check it out here: http://spring.neo4j.org/guide
64
Thursday, March 15, 12
106. The end (and the beginning!)
๏ See the Spring Data Neo4j site for more info:
http://spring.neo4j.org
๏ Check out the developer notes at GitHub:
http://spring.neo4j.org/notes
๏ Again, don’t miss our fantastic e-book on Spring Data Neo4j:
http://spring.neo4j.org/guide
๏ Spring Data Forum at
http://spring.neo4j.org/discussions
๏ All about Neo4j:
http://neo4j.org
๏ Neo4j videos and webinars:
http://video.neo4j.org
Thursday, March 15, 12
107. Cineasts.net
Check Out: http://spring.neo4j.org/tutorial
Thursday, March 15, 12