A general introduction to Spring Data / Neo4J

Preview:

DESCRIPTION

GraphDB Meetup Paris : 1st of October.

Citation preview

`whoami`

@fbiville @LateraIThoughts

:WORKS_FOR

:IS_R

EA

CH

AB

LE

{on: “Twitter”}

:IS_R

EA

CH

AB

LE

{on:

“Tw

itter

”}

:LOVES :IS_PARTNER_WITH

Calendar

ConferenceOctober / http://tinyurl.com/soft-shake-neo4j

Traininghttp://www.lateral-thoughts.com/formation-neo4j

BBL : just ping me!http://www.brownbaglunch.fr/baggers.html#Florent_Biville

On one side: graph databases!

Flock DB

On one side: graph databases!

Flock DBVERY

DYN

AMIC

LANDSC

APE

On the other side: the enterprise

On the other side: the enterprise

LIVE L

ONG AND P

ROSP

ER

The Enterprise Architecture

● Entities

● DAO

● Service

● Controllers

The Enterprise Architecture

● Entities

● DAO

● Service

● Controllers

?

featuring an Oh Real Monster!

Object-Relational Mapping

Applies only to Relational DBMS

Lowest common denominator

80% easy

20% … painful

Java and ORMs

Java Persistence API

JSR 220 - JSR 317

Main implementors

● EclipseLink

● Apache OpenJPA

● Hibernate

@Entity

@Table(name = "channels")

public class Channel {

@Id

@GeneratedValue(strategy = IDENTITY)

@Column(name = "id", nullable = false)

private long id;

@Column(name = "title", nullable = false,

unique = true)

private String title = "";

@Column(name = "description", nullable =

false)

private String description = "";

// [...]

}

Java and ORMs

Java Persistence API

JSR 220 - JSR 317

Main implementors

● EclipseLink

● Apache OpenJPA

● Hibernate

@Repository

public class CastRepository implements /.../ {

@PersistenceContext

private EntityManager entityManager;

@Override

@Transactional

public void delete(final Cast cast) {

entityManager.remove(cast);

}

@Override

@Transactional(readOnly = true)

public Cast findById(final long id) {

checkArgument(id >= 0);

return entityManager.find(Cast.class, id);

}

}

Java and ORMs: the good parts

Familiar programming model

● @Transactional [SPRING]

● @Entity, @Table...

● @Repository [SPRING]

Java and ORMs: the bad parts

Defines its own universe

see JPA entity lifecycle ;-(

Relation-Objects = 2 <> paradigms!

1+n query problem

inheritance strategies

SQL knowledge needed -> abstraction leak

What model REALLY is relational? :)

Why does Neo4J kick ass? cuz...

Graph = generic Data Structure

...and powerful ;-)

Natural fit with objects

Frictionless mapping!

Mapping with Neo4J?!

BUT No predefined schema

Labeled nodes can be very <>

Same with relationships

Schema-optionality = a problem?

see the awesome GraphGist challenge!

Schema-optionality = a problem?

Typical apps do not handle

gazillion of entities

More like a finite number

Let’s map then!

First approach: Hibernate OGM

Reuses Hibernate Core

Supports simple JP-QL queries

Support for Neo4J is a WIP

Let’s map then!

First approach: Hibernate OGM

Reuses Hibernate Core

Supports simple JP-QL queries

Support for Neo4J is a WIP

Lowest Common Denominator

Let’s map then!

Second approach: Tinkerpop Frames

Multi-graph DB support (Blueprints interface)

REST support with Tinkerpop REXSTER

Querying with Gremlin

Let’s map then!

Third approach: Spring Data Neo4J

Spring / Spring Data philosophy

Templates

Entities, “magic” repositories, @Transactional

Cypher support

Multi-store support

Spring Data

History ~2010

Rod Johnson, (was) VMWare

Emil Eifrem, Neo Technology

Spring Data

Familiar model for Spring apps

Thin common layer

Embraces diversity MongoDB

Redis

Neo4J

ElasticSearch…

Current version 2.3.1.RELEASE

vanilla Neo4J “repositories”

@Repositorypublic class BranchRepository {

private final GraphDatabaseService graphDB;

public Relationship createBranch(Node project, Node commit, Map<String,?> properties) {

try (Transaction tx = graphDB.beginTx()) {Relationship relationship = project.createRelationshipTo(

commit,DynamicRelationshipType.name("HAS_BRANCH")

);for (Entry<String,?> entry:properties.entrySet()) {

relationship.setProperty(entry.getKey(), entry.getValue());}tx.success();return relationship;

}}

vanilla Neo4J “repositories”

@Repositorypublic class BranchRepository {

private final GraphDatabaseService graphDB;

public Relationship createBranch(Node project, Node commit, Map<String,?> properties) {

try (Transaction tx = graphDB.beginTx()) {Relationship relationship = project.createRelationshipTo(

commit,DynamicRelationshipType.name("HAS_BRANCH")

);for (Entry<String,?> entry:properties.entrySet()) {

relationship.setProperty(entry.getKey(), entry.getValue());}tx.success();return relationship;

}}

vanilla Neo4J “repositories”

@Repositorypublic class BranchRepository {

private final GraphDatabaseService graphDB;

public Relationship createBranch(Node project, Node commit, Map<String,?> properties) {

try (Transaction tx = graphDB.beginTx()) {Relationship relationship = project.createRelationshipTo(

commit,DynamicRelationshipType.name("HAS_BRANCH")

);for (Entry<String,?> entry:properties.entrySet()) {

relationship.setProperty(entry.getKey(), entry.getValue());}tx.success();return relationship;

}}

Spring Data Neo4J repositories

public interface BranchRepository extends GraphRepository<Branch> {

}

Spring Data Neo4J repositories

What’s behind GraphRepository

Spring Data Commons - Repository

Marker interface, automatic discovery

Spring Data Commons - CRUDRepository

Create/Read/Update/Delete “boilerplate” operations

Spring Data Commons - PagingAndSortingRepository

Pagination/sorting facilities

Spring Data Neo4J - IndexRepository

Abstracts Neo4J Lucene capabilities

Spring Data Neo4J - TraversalRepository

Encapsulate Neo4J traversals

Spring Data Neo4J repositories

Write less, do more

public interface BranchRepository extends GraphRepository<Branch> {

Iterable<Branch> findByNameLike(String name);

@Query("MATCH (project:PROJECT)-[b:HAS_BRANCH]->(commit:COMMIT) RETURN b")

Page<Branch> lookMaIveGotPages();

Branch findByNameAndCommitIdentifierLike(String name, String commit);

}

Spring Data Neo4J repositories

Cypher DSL via CypherDSLRepository

Execute query = start(lookup("company", "Company", "name", param("name"))).

match(path().from("company").in("WORKS_AT").to("person")).

returns(identifier("person"));

Page<Person> result = repo.query(

query , map("name","Neo4j"), new PageRequest(1,10)

);

Spring Data Neo4J entities

Nodes

@NodeEntitypublic class Person {

@GraphIdprivate Long id;@Indexed(indexName="people-search", type=FULLTEXT) private String name;@RelatedTo(type="OWNS", enforceTargetType=true)private Car car;@RelatedToVia(type="FRIEND_OF", direction=Direction.INCOMING)private Iterable<Friendship> friendships;@GraphTraversal(traversal = PeopleTraversalBuilder.class,

elementClass = Person.class, params = "persons") private Iterable<Person> people;

}

Spring Data Neo4J entities

Relationships

@RelationshipEntity(type="FRIEND_OF")public class Friendship {

@StartNodeprivate Person person;@EndNodeprivate Dog humansBestFriend;@GraphProperty /* optional here ;-) */private Date since;/** * moaaaaar properties */

}

Spring Data Neo4J template

Pre-shaved yaks!

public class PersonRepositoryImpl extends CustomPersonRepository {@Autowired /* [SPRING ANNOTATION] */private Neo4jTemplate template;

public Iterable<Person> findAllByNameCustom(String name) {Index<Node> personFulltextIndex =

template.getIndex("people-search", Person.class);personFulltextIndex.query("name", format("*%s*", name));// [...]

}}

and moaaar: createNode, projectTo...

And so much more...

Geospatial queries

Cross-store support

Dynamic relationships

“Advanced” mapping

<dependency>

<groupId>org.springframework.

data</groupId>

<artifactId>spring-data-neo4j</artifactId>

<version>2.3.1.RELEASE</version>

</dependency>

And so much more...

Geospatial queries

Cross-store support

QueryDSL integration

“Advanced” mapping

<dependency>

<groupId>org.springframework.

data</groupId>

<artifactId>spring-data-neo4j</artifactId>

<version>2.3.1.RELEASE</version>

</dependency>

Going further

Experiment

http://projects.spring.io/spring-data-neo4j/

Discuss

https://groups.google.com/forum/#!forum/neo4jfr

Share

http://www.meetup.com/graphdb-france/

Calendar

ConferenceOctober / http://tinyurl.com/soft-shake-neo4j

Traininghttp://www.lateral-thoughts.com/formation-neo4j

BBL : just ping me!http://www.brownbaglunch.fr/baggers.html#Florent_Biville

?

Recommended