12. 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 = "";
// [...]
}
13. 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);
}
}
14. Java and ORMs: the good parts
Familiar programming model
● @Transactional [SPRING]
● @Entity, @Table...
● @Repository [SPRING]
15. 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
20. Schema-optionality = a problem?
Typical apps do not handle
gazillion of entities
More like a finite number
21. Let’s map then!
First approach: Hibernate OGM
Reuses Hibernate Core
Supports simple JP-QL queries
Support for Neo4J is a WIP
22. 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
23. Let’s map then!
Second approach: Tinkerpop Frames
Multi-graph DB support (Blueprints interface)
REST support with Tinkerpop REXSTER
Querying with Gremlin
24. Let’s map then!
Third approach: Spring Data Neo4J
Spring / Spring Data philosophy
Templates
Entities, “magic” repositories, @Transactional
Cypher support
Multi-store support
26. Spring Data
Familiar model for Spring apps
Thin common layer
Embraces diversity MongoDB
Redis
Neo4J
ElasticSearch…
Current version 2.3.1.RELEASE
27. vanilla Neo4J “repositories”
@Repository
public 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;
}
}
28. vanilla Neo4J “repositories”
@Repository
public 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;
}
}
29. vanilla Neo4J “repositories”
@Repository
public 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;
}
}
30. Spring Data Neo4J repositories
public interface BranchRepository
extends GraphRepository<Branch> {
}
31. 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
32. 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);
}
33. 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)
);
34. Spring Data Neo4J entities
Nodes
@NodeEntity
public class Person {
@GraphId
private 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;
}
35. Spring Data Neo4J entities
Relationships
@RelationshipEntity(type="FRIEND_OF")
public class Friendship {
@StartNode
private Person person;
@EndNode
private Dog humansBestFriend;
@GraphProperty /* optional here ;-) */
private Date since;
/**
* moaaaaar properties
*/
}
36. 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...
37. 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>
38. 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>