SlideShare une entreprise Scribd logo
1  sur  76
Télécharger pour lire hors ligne
$(Graph Meetup)> who am i
Florent Biville (@fbiville)
(Développeur [OSS]|formateur|associé) à
Co-créateur de Spring Meetup Paris (@interface21_ug)
Partenaire @Neo4j depuis 2012 (& formateur Neo4j !)
Spring Data Neo4j - au menu
1. Spring ?
2. Spring Data ?
3. Spring Data Neo4j ?
Spring ?
Spring
À ses débuts (2003)
Spring == Spring Framework == framework de DI
Dependency Injection - brefs rappels
Spring
public class InstantMessagingClient implements MessagingClient {
private final InstantMessagingService instantMessagingService;
private final UserSessionService userSessionService;
public InstantMessagingClient(InstantMessagingService instantMessagingService,
UserSessionService userSessionService) {
this.instantMessagingService = instantMessagingService;
this.userSessionService = userSessionService;
}
public void sendMessage(Message message) {
if (userSessionService.isCurrentlyLogged(message.getAuthorName())) {
instantMessagingService.sendMessage(message);
}
}
}
Spring
public class InstantMessagingClient implements MessagingClient {
private final InstantMessagingService instantMessagingService;
private final UserSessionService userSessionService;
public InstantMessagingClient(InstantMessagingService instantMessagingService,
UserSessionService userSessionService) {
this.instantMessagingService = instantMessagingService;
this.userSessionService = userSessionService;
}
public void sendMessage(Message message) {
if (userSessionService.isCurrentlyLogged(message.getAuthorName())) {
instantMessagingService.sendMessage(message);
}
}
}
Spring
Dependency Injection - idée
Ne pas assembler InstantMessagingClient soi-
même, déléguer plutôt à une brique logicielle tierce.
Spring
Dependency Injection - intérêts
Découpler son logiciel d’un “assemblage” particulier de
InstantMessagingClient (ex: assembler un service
de tests pour les tests automatisés)
Spring
Dependency Injection - avec Spring Framework
Spring
Notion de bean = description d’un “assemblage” = recette
de créations d’objets
Notion de context = groupe de beans
Plusieurs formats de description :
XML (historique), Java, annotations Java
Spring
Déclaration de context en XML Déclaration de context en Java
<beans[...]>
<import resource=”classpath:my-services.xml” />
<bean id=”instantMessagingClient” class=”com.
acme.InstantMessagingClient”>
<constructor-arg ref=”instantMsgService” />
<constructor-arg ref=”userSessionService” />
</bean>
</beans>
@Configuration
@Import(MyServiceContext.class)
public class MyProductionContext {
@Bean
public MessagingClient instantMessagingClient
(InstantMessagingService msgService,
UserSessionService userService)
return new InstantMessagingClient(
msgService, userService
);
}
Spring
Dependency Injection par annotation
Côté contexte : <component-scan /> (XML) ou @ComponentScan (Java) permet de
scanner tout un ensemble de beans sans avoir à les déclarer explicitement.
@Component
public class InstantMessagingClient implements MessagingClient {
[...]
@Autowired // ou @Inject (standard Java EE)
public InstantMessagingClient(InstantMessagingService instantMessagingService,
UserSessionService userSessionService) {
[...]
}
[...]
}
Spring
À ses débuts (2003)
Spring == Spring Framework == framework de DI
Devient un standard de facto (vs. le standard officiel J2EE)
Spring
Depuis,
Spring = écosystème alternatif|complémentaire à Java EE
Spring
Spring
La plupart des briques logicielles de l’écosystème Spring
repose sur Spring Framework...
Spring
… dont Spring Data !
Spring
Spring Data ?
Contexte historique
Hégémonie des RDBMS jusqu’à il y a “peu” (NOSQL!).
Impacts côté Java,
hégémonie des ORM (Hibernate, EclipseLink...)
émergence d’un standard (JPA)
Spring Data
Philosophie
Concilier
la familiarité des API comme JPA,
la flexibilité de Spring Framework,
les spécificités d’un maximum de stores NOSQL.
Spring Data
Spring Data
Spring Data
Objection !
Spring Data
Les ORM peuvent s’appuyer
sur le standard SQL commun aux SGDBR.
Spring Data
Il n’existe aucun standard partagé par les stores NOSQL.
Spring Data
Comment Spring Data peut-il
prétendre à une API homogène
autour de stores NOSQL qui ne le
sont pas ?
Spring Data
Spring Data Commons - idée
Module parent de tous les modules Spring Data.
Regroupe les traits communs des stores supportés.
Définit les concepts partagés de base.
Spring Data
Entité ~ description orientée objet d’un enregistrement
Repository ~ encapsulation des opérations de
requêtage sur une collection d’objets (ici : entités)
Template ~ encapsulation des opérations bas niveau
spécifiques à un service particulier (JdbcTemplate…)
Spring Data
Spring Data Commons - entités
Spring Data
Notion de mapping
représentation objet (entité) <-> représentation du store
chaque module SD implémente son propre mapping
exemples : @NodeEntity (SD Neo4j), @Document (SD Mongo)...
Spring Data
Spring Data Commons - repositories
Spring Data
Encapsule les contrats d’opérations de requêtage
communes à la plupart des stores : écriture, lecture, mise à
jour…
Ces opérations sont réparties dans une hiérarchie d’
interfaces Java.
Spring Data
Spring Data
Repository<T,
ID>
Interface “marker” permettant de
déclencher l’inclusion de ses
implémentations
automatiquement et la génération
de méthodes finder
dynamiques.
T = type de l’entité
ID = type de l’identifiant technique
Méthodes finder dynamiques
Idée : déduire (au runtime) l’implémentation des
méthodes de Repository par leur signature (merci Ruby on
Rails).
Spring Data
public interface PersonRepository extends Repository<Person, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findByLastnameIgnoreCase(String lastname);
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}
Spring Data
@Service
public class JdbcPersonService implements PersonService {
private final PersonRepository repository;
@Autowired
public PersonService(PersonRepository repository) {
this.repository = repository;
}
@Transactional
public List<Person> findByLastnameIgnoreCase(String lastName) {
return repository.findByLastnameIgnoreCase(lastName);
}
// [...]
}
Spring Data
Méthodes finder dynamiques
Aucune écriture d’implémentation de PersonRepository !
Les développeurs se focalisent sur le code métier
(JdbcPersonService).
Spring Data
Spring Data
Repository<T,
ID>
Interface “marker” permettant de
déclencher l’inclusion de ses
implémentations
automatiquement et la génération
de méthodes finder
dynamiques.
T = type de l’entité
ID = type de l’identifiant technique
Spring Data
Repository<T,
ID> Définit les opérations
élémentaires sur les entités
(création, lecture, mise à jour,
suppression).
CrudRepository<T,
ID>
T = type de l’entité
ID = type de l’identifiant technique
Spring Data
Repository<T,
ID>
Introduit des critères de tri &
pagination sur les requêtes de
lecture globale.
CrudRepository<T,
ID>
PagingAndSortingRepository<T, ID>
T = type de l’entité
ID = type de l’identifiant technique
Spring Data
Repository<T,
ID>
T = type de l’entité
ID = type de l’identifiant technique
CrudRepository<T,
ID>
PagingAndSortingRepository<T, ID>
Chaque module Spring Data (et
chaque développeur!) est ensuite
libre non seulement d’
implémenter mais de spécialiser
ces contrats transverses.
Comment Spring Data peut-il
prétendre à une API homogène
autour de stores NOSQL qui ne le
sont pas ?
Spring Data
En introduisant
1 API commune minimaliste
Mais aussi des extensions d’
API par type de store !
Spring Data
Exemple d’utilisation : Redbasin (article)
Idée : concilier l’immensité des informations disponibles
autour de la recherche de traitements contre le cancer
pour détecter au plus vite les traitements inefficaces.
Utilisation de Spring Data pour
Neo4j/Mongo DB/Redis/Hadoop.
Spring Data
Spring Data Neo4j ?
Module fils (historique!) de Commons
dédié à l’interfaçage avec … Neo4j,
fournit des entités, repositories,
templates orientés graphe !
Spring Data Neo4j
Version actuelle : 3.1.0.RELEASE.
Depuis 3.0.0.RELEASE (24 février 2014),
Neo4j 2.0 est officiellement supporté.
Spring Data Neo4j
Spring Data Neo4j - mapping & entités
Spring Data Neo4j
Deux types d’entités : @NodeEntity, @RelationshipEntity
Deux modes de mapping : simple & avancé
Plusieurs stratégies de représentation des métadonnées de
mapping au sein du graphe.
Spring Data Neo4j
Entités
@NodeEntity, @RelationshipEntity
Support basique de la JSR-303 (Bean Validation)
Projection de résultats de traversées possible (via
FieldTraversalDescriptionBuilder).
Cycle de vie à la JPA : detached, attached.
Spring Data Neo4j
@NodeEntity
public class Person {
@GraphId // Optionnel si utilisation du mapping avancé
private Long nodeId;
@Indexed(unique=true) // Index façon 2.0
private String id;
@Indexed(indexType = IndexType.FULLTEXT, indexName = "people") // Index legacy
@Size(min = 2, max = 50) // JSR-303
private String name;
@RelatedTo(type="OWNS", enforceTargetType=true) // @RelationshipEntity non requise
private Car car;
@RelatedToVia(type="FRIEND_OF", direction=Direction.INCOMING)
private Iterable<Friendship> friendships;
// [...] constructeurs, getters/setters, equals/hashCode
}
Spring Data Neo4j
@RelationshipEntity(type = "ACTS_IN")
public class Role {
@GraphId
private Long id;
@EndNode
private Movie movie;
@StartNode
private Actor actor;
private String name; // implicitement persisté (version explicite : @GraphProperty)
@GraphTraversal(traversal=PeopleTraversalBuilder.class, params="persons")
private Iterable<Relationship> peopleRelationships;
// [...] constructeurs, getters/setters, equals/hashCode
}
Spring Data Neo4j
Mapping avancé
Idée : intercepter les accès aux entités (classes
annotées @NodeEntity ou @RelationshipEntity) afin de les
enrichir d’informations supplémentaires.
Spring Data Neo4j
Mapping avancé
Aspects Neo4jRelationshipBacking et Neo4jNodeBacking.
Introduction d’un champ EntityState (~noeud /
relation sous-jacente) et de méthodes de
persistence (Active Record).
Spring Data Neo4j
Mapping simple
Chaque classe entité inclut explicitement un champ
annoté @GraphId (nécessairement de type Long) où sera
persisté l’ID technique des noeuds/relations.
Spring Data Neo4j
Mapping, côté graphe
Différentes stratégies de représentation possibles.
Spring Data Neo4j
Noeud <-> @NodeEntity Relation <-> @RelationshipEntity
LabelBasedNodeTypeRepresentationStrategy IndexBasedRelationshipTypeRepresentationStrategy
IndexBasedNodeTypeRepresentationStrategy
SubReferenceNodeTypeRepresentationStrategy NoopRelationshipTypeRepresentationStrategy
NoopNodeTypeRepresentationStrategy
Mapping, côté graphe
LabelBased (défaut pour noeuds): chaque noeud se voit
assigner un label correspondant au nom qualifié (ou
aliasé) de son entité Java.
Spring Data Neo4j
Mapping, côté graphe
IndexBased (défaut pour rels): un index __types__ est
créé où sont indexés les champs __type__ ajouté
automatiquement aux noeuds/relations
Spring Data Neo4j
Mapping, côté graphe
SubReference (legacy): l’arbre d’entités Java est
persisté comme un sous-graphe dans Neo4j. Les
noeuds du graphe s’y lient avec des relations de type
INSTANCE_OF. Il annule le mapping des relations (cf.
Noop).
Spring Data Neo4j
Mapping, côté graphe
Noop : ne fait rien (principalement utilisé pour les tests
internes à SDN) :)
Spring Data Neo4j
Le mapping entités-graphe est déclenché via l’utilisation
des repositories ou de Neo4jTemplate.
Spring Data Neo4j
Spring Data Neo4j - repositories
Spring Data Neo4j
Spring Data Neo4j
Repository<T,
ID>
CrudRepository<T,
ID>
PagingAndSortingRepository<T, ID>
GraphRepository<T>
Outre les opérations de base,
cette interface expose les
opérations d’indexations (pre- et
post-2.0) et de traversée via des
interfaces intermédiaires (non
illustrées ici) comme
findAllByTraversal…
T = type de l’entité
ID = type de l’identifiant technique
Spring Data Neo4j
// côté repository
public interface TweetRepository extends GraphRepository<Tweet> {
List<Tweet> findByPosterName(String poster);
}
// côté service
@Service
@Transactional
public class TwitterService implements SocialService {
@Autowired // préférez par constructeur ou par setter
private TweetRepository tweetRepository;
@Transactional(readOnly = true)
public Tweets findTweetsAuthoredBy(String poster) {
return Tweets.of(tweetRepository.findByPosterName(poster));
}
}
Il est également possible de définir des requêtes Cypher
particulières (toujours pas d’implémentation à écrire !)
public interface UserRepository extends GraphRepository<User> {
@Query( "MATCH (me:User {user:{name}})-[:POSTED]->(tweet)-[:MENTIONS]->(user)" +
" WHERE me <> user " +
" RETURN distinct user")
Set<User> suggestFriends(@Param("name") String user);
}
Spring Data Neo4j
Il existe aussi d’autres repositories tels que
SpatialRepository (requêtes géospatiales),
CypherDslRepository<T> pour utiliser le DSL Cypher
Java et des intégrations avec QueryDSL (voire de les
combiner).
Spring Data Neo4j
Spring Data Neo4j - template
Spring Data Neo4j
Encapsule l’API Neo4j avec une gestion implicite des
transactions (et une optimisation des requêtes HTTP en
mode REST).
Permet la manipulation des entités et offre un système
basique d’écoute d’événements (Spring Framework) :
{Before|After}{Save|Delete}Event
Spring Data Neo4j
Spring Data Neo4j - cross-store persistence
Spring Data Neo4j
Permet de persister une partie des informations portée par
les entités dans Neo4j et l’autre dans un SGDBR (via JPA).
Spring Data Neo4j
L’entité ne sera persistée dans le graphe qu’une fois
persistée dans le SGDBR (ID JPA assigné). Un champ
FOREIGN_ID (FQN + ID JPA) est ensuite ajouté au noeud
du graphe.
Les aspects de SDN rendent les champs annotés
@GraphProperty transients pour JPA.
Spring Data Neo4j
@Entity // JPA
@NodeEntity(partial = true) // Spring Data Neo4j
public class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "id_gen")
@TableGenerator(name = "id_gen", table = "SEQUENCE", pkColumnName = "SEQ_NAME",
valueColumnName = "SEQ_COUNT", pkColumnValue = "SEQ_GEN", allocationSize = 1)
private Long id; // ID JPA
private String name;
@GraphProperty
@Indexed
String nickname;
@RelatedToVia(type = "recommends", elementClass = Recommendation.class)
Iterable<Recommendation> recommendations;
}
Spring Data Neo4j
Conclusion
?Ça continue sur Twitter (@fbiville, @LateraIThoughts, @Neo4jFr),
le Google Groups Neo4jFR,
les meetups… ;-)

Contenu connexe

Similaire à [FR] Introduction à Spring Data Neo4j 3.x

Entity_framework_db first
Entity_framework_db firstEntity_framework_db first
Entity_framework_db firstZineb ELGARRAI
 
Linq et Entity framework
Linq et Entity frameworkLinq et Entity framework
Linq et Entity frameworkDNG Consulting
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web5pidou
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemeStéphane Traumat
 
Priows présentation des résultats
Priows présentation des résultats Priows présentation des résultats
Priows présentation des résultats Gilbert Paquette
 
Sudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesSudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesY. Nicolas
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPkemenaran
 
JUG Nantes - Telosys Tools - Avril 2014
JUG Nantes - Telosys Tools - Avril 2014 JUG Nantes - Telosys Tools - Avril 2014
JUG Nantes - Telosys Tools - Avril 2014 telosys
 
Telosys tools jug-nantes-2014-v1.2
Telosys tools jug-nantes-2014-v1.2Telosys tools jug-nantes-2014-v1.2
Telosys tools jug-nantes-2014-v1.2Laurent Guérin
 
03 Web Semantique
03  Web Semantique03  Web Semantique
03 Web Semantiquebadirh
 
GraphTour - Workday: Tracking activity with Neo4j (French version)
GraphTour - Workday: Tracking activity with Neo4j (French version)GraphTour - Workday: Tracking activity with Neo4j (French version)
GraphTour - Workday: Tracking activity with Neo4j (French version)Neo4j
 
Microservices-DDD-Telosys-Devoxx-FR-2022
Microservices-DDD-Telosys-Devoxx-FR-2022Microservices-DDD-Telosys-Devoxx-FR-2022
Microservices-DDD-Telosys-Devoxx-FR-2022Laurent Guérin
 
Framework Hibernate
Framework HibernateFramework Hibernate
Framework HibernateInes Ouaz
 
Formation JAVA/J2EE
Formation JAVA/J2EEFormation JAVA/J2EE
Formation JAVA/J2EEInes Ouaz
 

Similaire à [FR] Introduction à Spring Data Neo4j 3.x (20)

JPA est middleware
JPA est middleware JPA est middleware
JPA est middleware
 
Entity_framework_db first
Entity_framework_db firstEntity_framework_db first
Entity_framework_db first
 
Tutoriel java
Tutoriel javaTutoriel java
Tutoriel java
 
Linq et Entity framework
Linq et Entity frameworkLinq et Entity framework
Linq et Entity framework
 
Drools
DroolsDrools
Drools
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosysteme
 
Priows présentation des résultats
Priows présentation des résultats Priows présentation des résultats
Priows présentation des résultats
 
Sudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesSudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de données
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHP
 
Support cours j2_ee
Support cours j2_eeSupport cours j2_ee
Support cours j2_ee
 
JUG Nantes - Telosys Tools - Avril 2014
JUG Nantes - Telosys Tools - Avril 2014 JUG Nantes - Telosys Tools - Avril 2014
JUG Nantes - Telosys Tools - Avril 2014
 
Telosys tools jug-nantes-2014-v1.2
Telosys tools jug-nantes-2014-v1.2Telosys tools jug-nantes-2014-v1.2
Telosys tools jug-nantes-2014-v1.2
 
03 Web Semantique
03  Web Semantique03  Web Semantique
03 Web Semantique
 
GraphTour - Workday: Tracking activity with Neo4j (French version)
GraphTour - Workday: Tracking activity with Neo4j (French version)GraphTour - Workday: Tracking activity with Neo4j (French version)
GraphTour - Workday: Tracking activity with Neo4j (French version)
 
Microservices-DDD-Telosys-Devoxx-FR-2022
Microservices-DDD-Telosys-Devoxx-FR-2022Microservices-DDD-Telosys-Devoxx-FR-2022
Microservices-DDD-Telosys-Devoxx-FR-2022
 
Développement Sous Android
Développement Sous AndroidDéveloppement Sous Android
Développement Sous Android
 
Framework Hibernate
Framework HibernateFramework Hibernate
Framework Hibernate
 
Cours 01.pptx
Cours 01.pptxCours 01.pptx
Cours 01.pptx
 
Formation JAVA/J2EE
Formation JAVA/J2EEFormation JAVA/J2EE
Formation JAVA/J2EE
 

Plus de Florent Biville

DevFest Istanbul - a free guided tour of Neo4J
DevFest Istanbul - a free guided tour of Neo4JDevFest Istanbul - a free guided tour of Neo4J
DevFest Istanbul - a free guided tour of Neo4JFlorent Biville
 
A general introduction to Spring Data / Neo4J
A general introduction to Spring Data / Neo4JA general introduction to Spring Data / Neo4J
A general introduction to Spring Data / Neo4JFlorent Biville
 
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013Hands on Neo4J - Duchess France/Zenexity - 25/09/2013
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013Florent Biville
 
(R)évolutionnez vos bases de données avec Liquibase
(R)évolutionnez vos bases de données avec Liquibase(R)évolutionnez vos bases de données avec Liquibase
(R)évolutionnez vos bases de données avec LiquibaseFlorent Biville
 
Lightweight introduction to Scrum
Lightweight introduction to ScrumLightweight introduction to Scrum
Lightweight introduction to ScrumFlorent Biville
 

Plus de Florent Biville (6)

DevFest Istanbul - a free guided tour of Neo4J
DevFest Istanbul - a free guided tour of Neo4JDevFest Istanbul - a free guided tour of Neo4J
DevFest Istanbul - a free guided tour of Neo4J
 
A general introduction to Spring Data / Neo4J
A general introduction to Spring Data / Neo4JA general introduction to Spring Data / Neo4J
A general introduction to Spring Data / Neo4J
 
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013Hands on Neo4J - Duchess France/Zenexity - 25/09/2013
Hands on Neo4J - Duchess France/Zenexity - 25/09/2013
 
Liquibase en action
Liquibase en actionLiquibase en action
Liquibase en action
 
(R)évolutionnez vos bases de données avec Liquibase
(R)évolutionnez vos bases de données avec Liquibase(R)évolutionnez vos bases de données avec Liquibase
(R)évolutionnez vos bases de données avec Liquibase
 
Lightweight introduction to Scrum
Lightweight introduction to ScrumLightweight introduction to Scrum
Lightweight introduction to Scrum
 

[FR] Introduction à Spring Data Neo4j 3.x

  • 1.
  • 2. $(Graph Meetup)> who am i Florent Biville (@fbiville) (Développeur [OSS]|formateur|associé) à Co-créateur de Spring Meetup Paris (@interface21_ug) Partenaire @Neo4j depuis 2012 (& formateur Neo4j !)
  • 3. Spring Data Neo4j - au menu 1. Spring ? 2. Spring Data ? 3. Spring Data Neo4j ?
  • 5. Spring À ses débuts (2003) Spring == Spring Framework == framework de DI
  • 6. Dependency Injection - brefs rappels Spring
  • 7. public class InstantMessagingClient implements MessagingClient { private final InstantMessagingService instantMessagingService; private final UserSessionService userSessionService; public InstantMessagingClient(InstantMessagingService instantMessagingService, UserSessionService userSessionService) { this.instantMessagingService = instantMessagingService; this.userSessionService = userSessionService; } public void sendMessage(Message message) { if (userSessionService.isCurrentlyLogged(message.getAuthorName())) { instantMessagingService.sendMessage(message); } } } Spring
  • 8. public class InstantMessagingClient implements MessagingClient { private final InstantMessagingService instantMessagingService; private final UserSessionService userSessionService; public InstantMessagingClient(InstantMessagingService instantMessagingService, UserSessionService userSessionService) { this.instantMessagingService = instantMessagingService; this.userSessionService = userSessionService; } public void sendMessage(Message message) { if (userSessionService.isCurrentlyLogged(message.getAuthorName())) { instantMessagingService.sendMessage(message); } } } Spring
  • 9. Dependency Injection - idée Ne pas assembler InstantMessagingClient soi- même, déléguer plutôt à une brique logicielle tierce. Spring
  • 10. Dependency Injection - intérêts Découpler son logiciel d’un “assemblage” particulier de InstantMessagingClient (ex: assembler un service de tests pour les tests automatisés) Spring
  • 11. Dependency Injection - avec Spring Framework Spring
  • 12. Notion de bean = description d’un “assemblage” = recette de créations d’objets Notion de context = groupe de beans Plusieurs formats de description : XML (historique), Java, annotations Java Spring
  • 13. Déclaration de context en XML Déclaration de context en Java <beans[...]> <import resource=”classpath:my-services.xml” /> <bean id=”instantMessagingClient” class=”com. acme.InstantMessagingClient”> <constructor-arg ref=”instantMsgService” /> <constructor-arg ref=”userSessionService” /> </bean> </beans> @Configuration @Import(MyServiceContext.class) public class MyProductionContext { @Bean public MessagingClient instantMessagingClient (InstantMessagingService msgService, UserSessionService userService) return new InstantMessagingClient( msgService, userService ); } Spring
  • 14. Dependency Injection par annotation Côté contexte : <component-scan /> (XML) ou @ComponentScan (Java) permet de scanner tout un ensemble de beans sans avoir à les déclarer explicitement. @Component public class InstantMessagingClient implements MessagingClient { [...] @Autowired // ou @Inject (standard Java EE) public InstantMessagingClient(InstantMessagingService instantMessagingService, UserSessionService userSessionService) { [...] } [...] } Spring
  • 15. À ses débuts (2003) Spring == Spring Framework == framework de DI Devient un standard de facto (vs. le standard officiel J2EE) Spring
  • 16. Depuis, Spring = écosystème alternatif|complémentaire à Java EE Spring
  • 18. La plupart des briques logicielles de l’écosystème Spring repose sur Spring Framework... Spring
  • 19. … dont Spring Data ! Spring
  • 21. Contexte historique Hégémonie des RDBMS jusqu’à il y a “peu” (NOSQL!). Impacts côté Java, hégémonie des ORM (Hibernate, EclipseLink...) émergence d’un standard (JPA) Spring Data
  • 22. Philosophie Concilier la familiarité des API comme JPA, la flexibilité de Spring Framework, les spécificités d’un maximum de stores NOSQL. Spring Data
  • 26. Les ORM peuvent s’appuyer sur le standard SQL commun aux SGDBR. Spring Data
  • 27. Il n’existe aucun standard partagé par les stores NOSQL. Spring Data
  • 28. Comment Spring Data peut-il prétendre à une API homogène autour de stores NOSQL qui ne le sont pas ? Spring Data
  • 29. Spring Data Commons - idée Module parent de tous les modules Spring Data. Regroupe les traits communs des stores supportés. Définit les concepts partagés de base. Spring Data
  • 30. Entité ~ description orientée objet d’un enregistrement Repository ~ encapsulation des opérations de requêtage sur une collection d’objets (ici : entités) Template ~ encapsulation des opérations bas niveau spécifiques à un service particulier (JdbcTemplate…) Spring Data
  • 31. Spring Data Commons - entités Spring Data
  • 32. Notion de mapping représentation objet (entité) <-> représentation du store chaque module SD implémente son propre mapping exemples : @NodeEntity (SD Neo4j), @Document (SD Mongo)... Spring Data
  • 33. Spring Data Commons - repositories Spring Data
  • 34. Encapsule les contrats d’opérations de requêtage communes à la plupart des stores : écriture, lecture, mise à jour… Ces opérations sont réparties dans une hiérarchie d’ interfaces Java. Spring Data
  • 35. Spring Data Repository<T, ID> Interface “marker” permettant de déclencher l’inclusion de ses implémentations automatiquement et la génération de méthodes finder dynamiques. T = type de l’entité ID = type de l’identifiant technique
  • 36. Méthodes finder dynamiques Idée : déduire (au runtime) l’implémentation des méthodes de Repository par leur signature (merci Ruby on Rails). Spring Data
  • 37. public interface PersonRepository extends Repository<Person, Long> { List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List<Person> findByLastnameIgnoreCase(String lastname); List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); List<Person> findByLastnameOrderByFirstnameAsc(String lastname); List<Person> findByLastnameOrderByFirstnameDesc(String lastname); } Spring Data
  • 38. @Service public class JdbcPersonService implements PersonService { private final PersonRepository repository; @Autowired public PersonService(PersonRepository repository) { this.repository = repository; } @Transactional public List<Person> findByLastnameIgnoreCase(String lastName) { return repository.findByLastnameIgnoreCase(lastName); } // [...] } Spring Data
  • 39. Méthodes finder dynamiques Aucune écriture d’implémentation de PersonRepository ! Les développeurs se focalisent sur le code métier (JdbcPersonService). Spring Data
  • 40. Spring Data Repository<T, ID> Interface “marker” permettant de déclencher l’inclusion de ses implémentations automatiquement et la génération de méthodes finder dynamiques. T = type de l’entité ID = type de l’identifiant technique
  • 41. Spring Data Repository<T, ID> Définit les opérations élémentaires sur les entités (création, lecture, mise à jour, suppression). CrudRepository<T, ID> T = type de l’entité ID = type de l’identifiant technique
  • 42. Spring Data Repository<T, ID> Introduit des critères de tri & pagination sur les requêtes de lecture globale. CrudRepository<T, ID> PagingAndSortingRepository<T, ID> T = type de l’entité ID = type de l’identifiant technique
  • 43. Spring Data Repository<T, ID> T = type de l’entité ID = type de l’identifiant technique CrudRepository<T, ID> PagingAndSortingRepository<T, ID> Chaque module Spring Data (et chaque développeur!) est ensuite libre non seulement d’ implémenter mais de spécialiser ces contrats transverses.
  • 44. Comment Spring Data peut-il prétendre à une API homogène autour de stores NOSQL qui ne le sont pas ? Spring Data
  • 45. En introduisant 1 API commune minimaliste Mais aussi des extensions d’ API par type de store ! Spring Data
  • 46. Exemple d’utilisation : Redbasin (article) Idée : concilier l’immensité des informations disponibles autour de la recherche de traitements contre le cancer pour détecter au plus vite les traitements inefficaces. Utilisation de Spring Data pour Neo4j/Mongo DB/Redis/Hadoop. Spring Data
  • 48. Module fils (historique!) de Commons dédié à l’interfaçage avec … Neo4j, fournit des entités, repositories, templates orientés graphe ! Spring Data Neo4j
  • 49. Version actuelle : 3.1.0.RELEASE. Depuis 3.0.0.RELEASE (24 février 2014), Neo4j 2.0 est officiellement supporté. Spring Data Neo4j
  • 50. Spring Data Neo4j - mapping & entités Spring Data Neo4j
  • 51. Deux types d’entités : @NodeEntity, @RelationshipEntity Deux modes de mapping : simple & avancé Plusieurs stratégies de représentation des métadonnées de mapping au sein du graphe. Spring Data Neo4j
  • 52. Entités @NodeEntity, @RelationshipEntity Support basique de la JSR-303 (Bean Validation) Projection de résultats de traversées possible (via FieldTraversalDescriptionBuilder). Cycle de vie à la JPA : detached, attached. Spring Data Neo4j
  • 53. @NodeEntity public class Person { @GraphId // Optionnel si utilisation du mapping avancé private Long nodeId; @Indexed(unique=true) // Index façon 2.0 private String id; @Indexed(indexType = IndexType.FULLTEXT, indexName = "people") // Index legacy @Size(min = 2, max = 50) // JSR-303 private String name; @RelatedTo(type="OWNS", enforceTargetType=true) // @RelationshipEntity non requise private Car car; @RelatedToVia(type="FRIEND_OF", direction=Direction.INCOMING) private Iterable<Friendship> friendships; // [...] constructeurs, getters/setters, equals/hashCode } Spring Data Neo4j
  • 54. @RelationshipEntity(type = "ACTS_IN") public class Role { @GraphId private Long id; @EndNode private Movie movie; @StartNode private Actor actor; private String name; // implicitement persisté (version explicite : @GraphProperty) @GraphTraversal(traversal=PeopleTraversalBuilder.class, params="persons") private Iterable<Relationship> peopleRelationships; // [...] constructeurs, getters/setters, equals/hashCode } Spring Data Neo4j
  • 55. Mapping avancé Idée : intercepter les accès aux entités (classes annotées @NodeEntity ou @RelationshipEntity) afin de les enrichir d’informations supplémentaires. Spring Data Neo4j
  • 56. Mapping avancé Aspects Neo4jRelationshipBacking et Neo4jNodeBacking. Introduction d’un champ EntityState (~noeud / relation sous-jacente) et de méthodes de persistence (Active Record). Spring Data Neo4j
  • 57. Mapping simple Chaque classe entité inclut explicitement un champ annoté @GraphId (nécessairement de type Long) où sera persisté l’ID technique des noeuds/relations. Spring Data Neo4j
  • 58. Mapping, côté graphe Différentes stratégies de représentation possibles. Spring Data Neo4j Noeud <-> @NodeEntity Relation <-> @RelationshipEntity LabelBasedNodeTypeRepresentationStrategy IndexBasedRelationshipTypeRepresentationStrategy IndexBasedNodeTypeRepresentationStrategy SubReferenceNodeTypeRepresentationStrategy NoopRelationshipTypeRepresentationStrategy NoopNodeTypeRepresentationStrategy
  • 59. Mapping, côté graphe LabelBased (défaut pour noeuds): chaque noeud se voit assigner un label correspondant au nom qualifié (ou aliasé) de son entité Java. Spring Data Neo4j
  • 60. Mapping, côté graphe IndexBased (défaut pour rels): un index __types__ est créé où sont indexés les champs __type__ ajouté automatiquement aux noeuds/relations Spring Data Neo4j
  • 61. Mapping, côté graphe SubReference (legacy): l’arbre d’entités Java est persisté comme un sous-graphe dans Neo4j. Les noeuds du graphe s’y lient avec des relations de type INSTANCE_OF. Il annule le mapping des relations (cf. Noop). Spring Data Neo4j
  • 62. Mapping, côté graphe Noop : ne fait rien (principalement utilisé pour les tests internes à SDN) :) Spring Data Neo4j
  • 63. Le mapping entités-graphe est déclenché via l’utilisation des repositories ou de Neo4jTemplate. Spring Data Neo4j
  • 64. Spring Data Neo4j - repositories Spring Data Neo4j
  • 65. Spring Data Neo4j Repository<T, ID> CrudRepository<T, ID> PagingAndSortingRepository<T, ID> GraphRepository<T> Outre les opérations de base, cette interface expose les opérations d’indexations (pre- et post-2.0) et de traversée via des interfaces intermédiaires (non illustrées ici) comme findAllByTraversal… T = type de l’entité ID = type de l’identifiant technique
  • 66. Spring Data Neo4j // côté repository public interface TweetRepository extends GraphRepository<Tweet> { List<Tweet> findByPosterName(String poster); } // côté service @Service @Transactional public class TwitterService implements SocialService { @Autowired // préférez par constructeur ou par setter private TweetRepository tweetRepository; @Transactional(readOnly = true) public Tweets findTweetsAuthoredBy(String poster) { return Tweets.of(tweetRepository.findByPosterName(poster)); } }
  • 67. Il est également possible de définir des requêtes Cypher particulières (toujours pas d’implémentation à écrire !) public interface UserRepository extends GraphRepository<User> { @Query( "MATCH (me:User {user:{name}})-[:POSTED]->(tweet)-[:MENTIONS]->(user)" + " WHERE me <> user " + " RETURN distinct user") Set<User> suggestFriends(@Param("name") String user); } Spring Data Neo4j
  • 68. Il existe aussi d’autres repositories tels que SpatialRepository (requêtes géospatiales), CypherDslRepository<T> pour utiliser le DSL Cypher Java et des intégrations avec QueryDSL (voire de les combiner). Spring Data Neo4j
  • 69. Spring Data Neo4j - template Spring Data Neo4j
  • 70. Encapsule l’API Neo4j avec une gestion implicite des transactions (et une optimisation des requêtes HTTP en mode REST). Permet la manipulation des entités et offre un système basique d’écoute d’événements (Spring Framework) : {Before|After}{Save|Delete}Event Spring Data Neo4j
  • 71. Spring Data Neo4j - cross-store persistence Spring Data Neo4j
  • 72. Permet de persister une partie des informations portée par les entités dans Neo4j et l’autre dans un SGDBR (via JPA). Spring Data Neo4j
  • 73. L’entité ne sera persistée dans le graphe qu’une fois persistée dans le SGDBR (ID JPA assigné). Un champ FOREIGN_ID (FQN + ID JPA) est ensuite ajouté au noeud du graphe. Les aspects de SDN rendent les champs annotés @GraphProperty transients pour JPA. Spring Data Neo4j
  • 74. @Entity // JPA @NodeEntity(partial = true) // Spring Data Neo4j public class User { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "id_gen") @TableGenerator(name = "id_gen", table = "SEQUENCE", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SEQ_GEN", allocationSize = 1) private Long id; // ID JPA private String name; @GraphProperty @Indexed String nickname; @RelatedToVia(type = "recommends", elementClass = Recommendation.class) Iterable<Recommendation> recommendations; } Spring Data Neo4j
  • 76. ?Ça continue sur Twitter (@fbiville, @LateraIThoughts, @Neo4jFr), le Google Groups Neo4jFR, les meetups… ;-)