2. Most active Spring project
Convenient data access to (No)SQL databases
Consistent API’s
Mapping POJOs, Template, Repositories
Neo4j, JPA, MongoDB, Redis, CouchBase & more
Spring Data
GraphAware®
3. Focus on performance
Based on a pure Java OGM [Neo4j-OGM]
3 Drivers available to connect to Neo4j
HTTP
Embedded
Bolt
Spring Data Neo4j 4.1
GraphAware®
4. Object Graph Mapping from any Java or JVM-based application
“Vampire” metadata scanning (no reflection!)
“Smart” object mapping
Mapping contexts tied to Session lifetimes
Application
HTTP session/request etc.
Support for default and bespoke type conversions
Repositories, Neo4jTemplate [SDN]
Custom Queries, Derived Finders [SDN]
Transactional Support
Features
GraphAware®
5. Persistence horizon (depth) indicates how many relationships
should be traversed in the graph when loading or saving data
Default loading depth is 1
Default persistence depth is -1
Variable Depth Persistence
GraphAware®
6. It’s a bird, it’s a plane,
it’s a superhero graph!
7. Node Entities - Character
GraphAware®
@NodeEntity(label = "Character")
public class Character {
@GraphId Long graphId;
…
private Long id;
private String name;
private String alias;
private String realName;
8. Node Entities - Relationships
GraphAware®
public class Character {
…
@Relationship(type = "ALLY_OF", direction = Relationship.UNDIRECTED)
@Relationship(type = "ENEMY_OF", direction = Relationship.UNDIRECTED)
@Relationship(type = "MEMBER_OF")
@Relationship(type = "STARS", direction = Relationship.INCOMING)
Set<Character> allies = new HashSet<>();
Set<Character> enemies = new HashSet<>();
Set<Team> teams = new HashSet<>();
Set<Role> roles = new HashSet<>();
Set<Game> gamesFeaturedIn = new HashSet<>();
@Relationship(type = "FEATURED_IN")
@Relationship(type = "FEATURED_IN")
Set<Comic> comicsFeaturedIn = new HashSet<>();
9. Node Entities - Hierarchy
GraphAware®
public class Villain extends Character{
…
}
public class Hero extends Character {
…
}
@NodeEntity(label = "Hero")
@NodeEntity(label = "Villain")
10. Node Entities - Team
GraphAware®
@NodeEntity(label = "Team")
public class Team {
@GraphId private Long graphId;
private Long id;
private String name;
private String operationsBase;
@Relationship(type = "MEMBER_OF",
direction = "INCOMING")
private Set<Character> members = new HashSet<>();
public Team() {
}
11. Node Entities - Comic
GraphAware®
@NodeEntity(label = "Comic")
private Long id;
private String title;
private String author;
private String artist;
private boolean available;
private Binding binding;
@DateLong
private Date onSaleDate;
@Relationship(type = "FEATURED_IN", direction = Relationship.INCOMING)
private Set<Character> characters = new HashSet<>();
public enum Binding {
SOFT,
LEATHER,
CLOTH,
HARD
}
public class Comic {
@GraphId private Long graphId;
12. Node Entities - Game
GraphAware®
@NodeEntity(label = "Game")
public class Game {
@Graphid private Long graphId;
private Long id;
private String title;
private int year;
private String publisher;
private Rating rating;
private Set<Platform> platforms;
@Relationship(type = "FEATURED_IN",
direction = Relationship.INCOMING)
private Set<Character> characters = new HashSet<>();
public enum Platform {
PC,
WII,
XBOX_360,
PLAYSTATION_3
}
13. Node Entities
GraphAware®
@Convert(UrlConverter.class)
private URL imdbUrl;
@Relationship(type = "STARS")
private Set<Role> stars;
public class UrlConverter implements
AttributeConverter<URL, String> {
@Override
public String toGraphProperty(URL value) {
return value == null? null : value.toString();
}
@Override
public URL toEntityAttribute(String value) {
try {
return new URL(value);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
@NodeEntity(label = "Movie")
public class Movie {
@GraphId private Long graphId;
private Long id;
private String title;
private int year;
private Rating rating;
15. Repositories
GraphAware®
public interface CharacterRepository<T extends Character> extends GraphRepository<T> {
List<T> findByNameLike(String keyword);
@Query(" MATCH (c:Character) WHERE ID(c)={characterId} " +
"OPTIONAL MATCH (c)-[:ALLY_OF|ENEMY_OF]-(other) " +
"WITH c, collect(other) as others " +
"OPTIONAL MATCH (c)-[:MEMBER_OF|FEATURED_IN]->
()<-[:MEMBER_OF|FEATURED_IN]-(teamMember) " +
"WITH c, others + collect(teamMember) as othersWithTeam " +
"OPTIONAL MATCH (c)<-[:STARS]-()-[:STARS]->(actors) " +
"WITH othersWithTeam + collect(actors) as allOthers " +
"UNWIND allOthers as related " +
"WITH count(*) as count, related " +
"RETURN related ORDER BY count DESC")
List<Character> findRelatedCharacters(@Param("characterId") Long id);