Accueil > DynaResume, JPA, JPA/EclipseLink, JPA/Hibernate > Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step16]

Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step16]


Dans le billet précédant [step15] nous avons créé les bases de données H2 et Derby constitué d’une table T_USER. Nous avons développé un petit code Java qui se connecte via JDBC à la base de données pour afficher la liste des User. Dans ce billet nous allons mettre en place JPA en mode « standalone » (sans utiliser un conteneur JPA) et développer des petits exemples qui récupère un User, une liste de User, qui insère un User dans la table T_USER des bases de données H2 et Derby avec les 2 implémentations JPA JPA/Hibernate et JPA/Eclipse Link :

Nous développerons les exemples décrits ci-dessus, avec les 2 implémentations JPA et les 2 bases de données :

Vous pouvez télécharger le zip org.dynaresume_step16.zip qui contient les projets expliqués ci dessous:

  • org.dynaresume.test.jpa.hibernate : examples avec JPA/Hibernate.
  • org.dynaresume.test.jpa.eclipselink : examples avec JPA/Eclipse Link.
  • spring-target-platform-dao : librairies JARs récupérés via Maven dans le billet [step14].
  • org.dynaresume.test.jpa : fusion des 2 projets org.dynaresume.test.jpa.hibernate et org.dynaresume.test.jpa.eclipselink pour montrer qu’il est possible d’avoir plusieurs implémentations JPA dans un même projet.

Pré-requis

Avant de démarrer ce billet vous devez avoir :

Téléchargez le zip spring-target-platform-dao.zip qui contient les librairies JARs JPA, JPA/Hibernate,… récupérés via Maven dans le billet [step14] puis importez le projet spring-target-platform-dao dans votre workspace.

REMARQUE : nous avons créé la base de données via des scripts mais JPA est capable de générer la base de données en utilisant les informations de mapping.

JPA

ORM c’est quoi?

La plupart des projets s’appuient sur une base de données pour gérer leur données persistantes. La récupération/mise à jour de ces données s’effectuent via des requêtes SQL. En Java ceci s’effectue via l’API JDBC (Java DataBase Connectivity) ou la plupart des bases de données fournissent un driver JDBC pour exécuter des requêtes SQL en Java.

Avant l’arrivée de l’ORM, le développeur devait exécuter des requêtes SQL puis construire des POJO Java en récupérant les résultat des requêtes SQL Select. La mise à jour de la base de données s’effectuait via des requêtes SQL Insert/Update. Ce procédé était assez lourd à mettre en œuvre et des frameworks d’ORM ont fait leur apparition. Au lieu de manipuler directement la base de données, l’ORM permet de manipuler des instances POJO Java qui deviennent persistantes. Pour cela un mapping entre des classes POJO et les tables de la base doivent être effectués. Par exemple dans notre cas nous allons mapper les getter/setter login de la classe User avec la colonne USR_LOGIN_C de la table T_USER :

JPA c’est quoi?

L’un des premiers frameworks d’ORM en Java qui a vu le jour est Hibernate. Face au succès de ce framework, Sun a décidé de créer une spécification standard d’ORM qui s’appele JPA (Java Persistente API) et qui fait partie de la spécification EJB3. JPA est une API autrement dit elle ne fournit pas l’implémentation mais que des interfaces. Dans notre cas nous allons utiliser les implémentations JPA JPA/Hibernate et JPA/Eclipse Link.

Un conteneur JPA c’est quoi?

JPA peut être ensuite utilisé en « standalone » ou dans un conteneur JPA. Un conteneur JPA permet de

  • gérer les connections (ouverture/fermeture). En JPA on parle de EntityManager.
  • gérer les transactions (commit/rollback). En JPA on parle de EntityTransaction.

Le conteneur JPA décharge ainsi le développeur de ces problématiques et de ce travail fastidieux et évite de nombreux bugs d’oubli de fermeture de connexion par exemple.

EJB3 joue le rôle d’un conteneur JPA. Spring fournit aussi un support JPA et joue ainsi le rôle de conteneur JPA. Dans ce billet nous allons utiliser JPA en mode « standalone » et nous verrons dans le prochain billet comment utiliser Spring dans un contexte JPA et montrerons l’intérêt d’utiliser Spring avec JPA.

JPA – Principe

Voici grossièrement les différents concepts sur lequel s’appuie JPA :

  • mapping qui permet de mapper les POJO avec les tables de la base de données.
  • persistence.xml qui est le fichier de configuration JPA, qui permet de définir plusieurs unité de persistances (persistence-unit) qui décrivent l’implémentation JPA à utiliser, les informations de connection à la base de données, les classes persistantes du projet…
  • EntityManagerFactory est chargé à partir d’une configuration persistence-unit et est utilisé pour obtenir un EntityManager qui est utilisé pour récupérer des POJO persistants, rendre persistent un POJO…

Mapping

JPA comme tout autre frameworks d’ORM nécéssite de définir un mapping entre les classes Java POJO (Domain) et les Tables de la base de données. En JPA ceci peut s’effectuer de 2 manières :

  • via un fichier XML orm.xml.
  • via des annotations Java.

Dans notre cas nous allons mettre en place le mapping via des Annotations.

persistence.xml

La configuration JPA s’effectue via un fichier nommé persistence.xml qui doit être stocké dans le répertoire META-INF. Voici un exemple de fichier XML persistence.xml que nous allons mettre en place :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-hibernate-h2"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.hibernate.ejb.HibernatePersistence
		</provider>

		<class>org.dynaresume.domain.User</class>

		<properties>
			<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
			<property name="hibernate.connection.url" value="jdbc:h2:C:/db/h2/dynaresume" />
			<property name="hibernate.connection.username" value="sa" />
			<property name="hibernate.connection.password" value="" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
			<property name="hibernate.show_sql" value="true" />
		</properties>

	</persistence-unit>

</persistence>

REMARQUE : la déclaration provider/class/properties doit s’effectuer dans cet ordre si on souhaite être conforme au schema XML persistence_1_0.xsd. Si vous déclarez dans l’odre provider/properties/class ceci fonctionne très bien avec du JPA « standalone », mais plus avec Spring ORM.

Ce fichier permet de configurer plusieurs persistence-unit qui pour chacun d’eux définissent :

  • l’implémentation JPA à utiliser via l’élement XML provider. Dans cet exemple cet élément provider est renseigné via org.hibernate.ejb.HibernatePersistence implémentation Hibernate de JPA.
  • les classes persistentes du projet (qui sont mappés avec les tables de la base de données) via les éléments XML class.
  • les informations de connection à la base de données via les éléments XML property.

EntityManagerFactory

La configuration JPA d’une unité de persistance persistence-unit (de nom dynaresume-hibernate-h2) décrite dans le fichier META-INF/persistence.xml est chargée dans une factory de gestionnaire d’entités EntityManagerFactory comme ceci :

String persistentUnitName = "dynaresume-hibernate-h2";
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistentUnitName);

Elle permet de récupérer ensuite un gestionnaire d’entité EntityManager :

EntityManager entityManager = entityManagerFactory.createEntityManager();

A partir de ce gestionnaire d’entité, nous pouvons ensuite récupérer des entités persistentes (POJO Java), les mettre à jour… Par exemple voici le code qui permet de récupérer le User d’id 1 :

User user = entityManager.find(User.class, (long) 1);

Ce code engendre une requête Select SQL.

Voici le code qui permet de rendre persistent un POJO User (d’insérer un User) :

User user = new User("jpa-user", "");
entityManager.persist(user);

Ce code engendre une requête Insert SQL.

Dans mes billets traitant JPA, je ne vais PAS parler d’une utilisation avancée des mappings JPA, mais nous allons nous concentrer sur la factory de gestion d’entités JPA EntityManagerFactory. Dans ce billet une utilisation « standalone » de la factory EntityManagerFactory sera expliqué pour comprendre les principes de JPA. Nous verrons dans le billet suivant l’interêt d’utiliser JPA dans un conteneur géré par Spring. Si vous ne connaissez pas JPA, je vous conseille vivement de lire 43. JPA (Java Persistence API) qui décrit très bien tous les mappings possibles que l’on peut effectuer avec JPA.

Etapes pour mise en place JPA

Cette section liste les étapes à suivre pour mettre en place JPA dans un projet. Elle récapitule tout ce que nous allons effectuer en détail dans la section JPA/Hibernate – H2.

  1. Ajoutez les librairies JARs requises pour JPA :
    • API JPA : com.springsource.javax.persistence-2.0.0.jar
    • API Transaction : com.springsource.javax.transaction-1.1.0.jar
    • Implémentation JPA. Dans le cas d’hibernate pensez à ajouter l’implémentation SFL4J (ex : avec log4j).
    • Driver JDBC de la base que l’on souhaite utiliser.
  2. Définir le fichier persistence.xml dans le répertoire META-INF :
    1. en définissant un persistence-unit nommé.
    2. en indiquant l’implémentation JPA dans le persistence-unit via un provider.
    3. en configurant les paramètres de connections à la base de données (Driver JDBC, URL Base..). les properties
  3. Définir le mapping POJO-Table via des annotations ou un fichier orm.xml.
  4. Ouvrir/Fermer une connection avec l’EntityManager.
  5. Ouvrir/Fermer une Transaction EntityTransaction lors d’une MAJ.

JPA/Hibernate

Dans cette section nous allons mettre en place l’implémentation Hibernate de JPA et utiliser ensuite JPA pour afficher la liste des Users dans la console. Pour cette implémentation JPA nous allons écrire le code nécéssaire pour JPA pas à pas ce qui permettra de soulever toutes les erreurs que l’on peut avoir lorsque l’on met en place JPA.
Les JARs que nous allons utiliser sont ceux qui ont été récupéré via Maven dans le zip spring-target-platform-dao.zip. Ce zip contient le projet Eclipse spring-target-platform-dao que vous devez importer dans votre workspace.

Initialisation projet org.dynaresume.test.jpa.hibernate

Créez le projet Java org.dynaresume.test.jpa.hibernate.

Librairie JPA

Ajoutez les JARs :

JAR Description
lib/javax/com.springsource.javax.persistence-2.0.0.jar API JPA « OSGifiée ».

User (sans annotations)

Créez la classe org.dynaresume.domain.User (sans annotations JPA) comme suit :

package org.dynaresume.domain;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;

	private String login;
	private String password;

	public User(String login, String password) {
		setLogin(login);
		setPassword(password);
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

REMARQUE : L’implémentation de l’interface java.io.Serializable n’est pas nécéssaire dans un contexte JPA.

JPA/Hibernate – H2

Dans cette section nous allons mettre en place JPA avec Hibernate en utilisant la base de donnée H2 :

FindUserDynaresumeH2Hibernate (EntityManager#find avec H2)

Ici nous allons créer la classe FindUserDynaresumeH2Hibernate qui va afficher le User d’ID 1 de la base H2 via l’implémentation JPA Hibernate en utilisant

EntityManager#find(Class entityClass, Object primaryKey)

Créez la classe org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate comme suit :

package org.dynaresume.test.jpa.hibernate.h2;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class FindUserDynaresumeH2Hibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			User user = entityManager.find(User.class, (long) 1);
			if (user == null) {
				System.out.println("User NOT founded.");
			} else {
				System.out.println("User founded login=" + user.getLogin());
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
f		}
	}
}

Voici l’explication de ce code :

  1. Récupération du gestionnaire d’entité JPA EntityManager via sa factory EntityManager Factory chargée par la configuration JPA persistence-unit de nom dynaresume-hibernate-h2 :
    String persistentUnitName = "dynaresume-hibernate-h2";
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistentUnitName);
    EntityManager entityManager = entityManagerFactory.createEntityManager();

    REMARQUE : a ce stade nous n’avons pas encore défini la configuration JPA persistence-unit.

  2. Récupération de l’entité persistente User d’id 1 via le gestionnaire d’entité JPA EntityManager, qui effectuera un Select SQL dans la table T_USER :
    User user = entityManager.find(User.class, (long) 1);
  3. Fermeture du gestionnaire d’entité JPA EntityManager et de sa factory EntityManagerFactory:
    entityManager.close();
    entityManagerFactory.close();

Lancez la classe FindUserDynaresumeH2Hibernate et vous verrez cette erreur dans la console :

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named dynaresume-hibernate-h2
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:84)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:16)

Cette erreur est normal car nous n’avons pas encore défini de fichier persistence.xml dans le répertoire META-INF de notre projet.

persistence.xml

Ici nous allons créer le fichier persistence.xml dans le répertoire META-INF que vous devez créer dans le répertoire src (et pas à la racine du projet comme les bundles OSGi). En effet ce fichier doit se retrouver après compilation du projet dans le répertoire bin. Créez le fichier persistence.xml avec le contenu suivant :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-hibernate-h2" transaction-type="RESOURCE_LOCAL">
	
	</persistence-unit>

</persistence>

Après compilation du projet, vérifiez que ce fichier est bien contenu dans le répertoire bin du projet Eclipse org.dynaresume.test.jpa.hibernate.

Relancez et vous pourrez constater la même erreur :

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named dynaresume-hibernate-h2
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:84)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:16)

Je trouve cette erreur assez perturbante car elle ne nous permet pas de distinguer le cas où le persistence-unit est définit au cas où il n’est pas définit. Cette erreur s’explique par le fait que nous n’avons pas indiqué l’implémentation JPA que nous souhaitons utiliser.

provider

L’implémentation JPA que nous souhaitons utiliser renseigné dans l’élement XML provider. Cet élement provider doit être renseigné par une classe qui implémente l’interface JPA javax.persistence.spi.PersistenceProvider. Dans notre cas nous souhaitons utiliser l’implémentation JPA Hibernate. Pour cela ajoutez l’élement provider comme suit :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-hibernate-h2"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.hibernate.ejb.HibernatePersistence
		</provider>

	</persistence-unit>

</persistence>

Relancez et vous pourrez constater la même erreur :

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named dynaresume-hibernate-h2
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:84)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:16)

Cette erreur s’explique par le fait que la classe org.hibernate.ejb.HibernatePersistence n’est pas trouvée dans le ClassLoader ce qui est normal car nous n’avons pas encore ajouté les JARs JPA/Hibernate.

Librairies Implémentation JPA

Ajoutez les librairies JPA Hibernate lib/jpa-hibernate/*.jar à votre projet.

Relancez et vous aurrez l’erreur suivante :

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:189)

Cette erreur s’explique par le fait que aucune implémentation de SL4J n’est trouvée. SFL4J (Simple Logging Facade for Java) est une facade de logs comme ce que propose l’API commons-logging. Cependant SFL4J est utilisé dans plus en plus de projets (Spring, Hibernate…) car il permet entre autres de régler les problèmes de ClassLoading. Je vous conseille de lire l’article Commons-logging VS SLF4J pour plus d’information à ce sujet.

Ajoutez les lib d’implémentation de SFL4J (log4j) lib/slf4j-log4j/*.jar à votre projet.

Relancez et la console affiche un warning (log4j) et une erreur :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: dynaresume-hibernate-h2] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:78)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:16)
Caused by: org.hibernate.HibernateException: 'hibernate.dialect' must be set when no Connection avalable
at org.hibernate.dialect.resolver.DialectFactory.buildDialect(DialectFactory.java:107)

Cette erreur s’explique par le fait que le dialect Hibernate (dialect de la base de donnée à utiliser) doit être configuré. Mais d’autres propriétés doivent être aussi configurés (Driver JDBC, URL de la base….). Ces configurations s’effectuent via l’élement XML properties.

properties

Modifiez le fichier persistence.xml avec les propriétés suivantes :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-hibernate-h2"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.hibernate.ejb.HibernatePersistence
		</provider>

		<properties>
			<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
			<property name="hibernate.connection.url" value="jdbc:h2:C:/db/h2/dynaresume" />
			<property name="hibernate.connection.username" value="sa" />
			<property name="hibernate.connection.password" value="" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
			<property name="hibernate.show_sql" value="true" />
		</properties>

	</persistence-unit>

</persistence>

Voici l’explication de ces propriétés :

Nom propriété Valeur propriété Description propriété
hibernate.connection.driver_class org.h2.Driver Configuration du driver JDBC de la base de données H2.
hibernate.connection.url jdbc:h2:C:/db/h2/dynaresume Configuration de l’URL de la base de données H2 de dynaresume.
hibernate.connection.username sa Configuration de l’utilisateur de la base de données H2 de dynaresume.
hibernate.connection.password Configuration du mot de passe de la base de données H2 de dynaresume.
hibernate.dialect org.hibernate.dialect.H2Dialect Dialect à utiliser pour générer les requêtes SQL pour la base de données H2.
hibernate.show_sql true Affiche les requêtes SQL.

Ici on peut constater que le nom des propriétés est lié à l’implémentation JPA. En JPA 2.0 les propriétés commune (driver JDBC….) sont standardisées.

Relancez et la console affiche un warning (log4j) et une erreur :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: dynaresume-hibernate-h2] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:78)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:16)
Caused by: org.hibernate.HibernateException: JDBC Driver class not found: org.h2.Driver
at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:89)

Cette erreur s’explique par le fait que nous n’avons pas encore mis le JAR du Driver JDBC de H2.

Ajoutez la librairie H2 lib/h2/com.springsource.org.h2-1.0.71.jar à votre projet :

JAR Description
lib/h2/com.springsource.org.h2-1.0.71.jar Base H2 « OSGifiée ».

Relancez et la console affiche un warning (log4j) et une erreur :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/SystemException
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:39)
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:34)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:17)
Caused by: java.lang.ClassNotFoundException: javax.transaction.SystemException

Cette erreur s’explique par le fait qu’il nous manque la librairie de transaction.

Ajoutez la librairie de Transaction lib/javax/com.springsource.javax.transaction-1.1.0.jar à votre projet.

JAR Description
lib/javax/com.springsource.javax.transaction-1.1.0.jar API Transaction « OSGifiée ».

Relancez et la console affiche un warning (log4j) et une erreur :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.IllegalArgumentException: Unknown entity: org.dynaresume.domain.User
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:193)
at org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeH2Hibernate.main(FindUserDynaresumeH2Hibernate.java:19)
Caused by: org.hibernate.MappingException: Unknown entity: org.dynaresume.domain.User

Cette erreur s’explique par le fait que la classe User est inconnu de JPA.

class

La configuration JPA doit lister toutes les classes persistantes via l’élement XML class :

<class>org.dynaresume.domain.User</class>

Modifiez le fichier persistent.xml en ajoutant la classe User en tant que classe persistante :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-hibernate-h2"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.hibernate.ejb.HibernatePersistence
		</provider>
                
		<class>org.dynaresume.domain.User</class>

		<properties>
			<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
			<property name="hibernate.connection.url" value="jdbc:h2:C:/db/h2/dynaresume" />
			<property name="hibernate.connection.username" value="sa" />
			<property name="hibernate.connection.password" value="" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
			<property name="hibernate.show_sql" value="true" />
		</properties>
		
	</persistence-unit>

</persistence>

Relancez et la même erreur s’affiche ce qui est normal car nous n’avons pas encore défini le mapping.

User – Mapping

Modifiez la classe User pour définir le mapping entre cette classe et la table T_USER comme suit :

package org.dynaresume.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "T_USER")
public class User {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "USR_ID_N")
	private long id;

	@Column(name = "USR_LOGIN_C")
	private String login;

	@Column(name = "USR_PASSWORD_C")
	private String password;

	public User() {
	}

	public User(String login, String password) {
		setLogin(login);
		setPassword(password);
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

Le champs id de la classe User est mappé comme ceci :

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USR_ID_N")
private long id;

Voici les explications de ce mapping :

  • @Column(name = « USR_ID_N ») indique que le champs id de la classe User est mappé avec la colonne USR_ID_N de la table T_User.
  • @Id indique que ce champs définit un identifiant (clé primaire).
  • @GeneratedValue(strategy = GenerationType.IDENTITY) indique que ce champs est mis à jour automatiquement lors d’une insertion en utilisant la stratégie IDENTITY. Cette stratégie permet d’utiliser le type IDENTITY qui est supporté à la fois par H2 et Derby. Ici nous avons la chance que ces 2 bases supportent le même type. Dans le cas ou on souhaiterait utiliser Oracle (support des sequences) et H2 (support Identity) avec JPA, on ne peut pas mettre de stratégie en commun (excepté celle de TABLE). Je parle un petit peu de cette problématique dans la section @GeneratedValue.

Relancez et vous devez voir dans la console la requête SQL de Select et le User d’ID 1 de la table T_USER de la base H2 :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select user0_.USR_ID_N as USR1_0_0_, user0_.USR_LOGIN_C as USR2_0_0_, user0_.USR_PASSWORD_C as USR3_0_0_ from T_USER user0_ where user0_.USR_ID_N=?
User founded login=angelo (H2)
log4j

Pour éviter le warn log4j, il suffit d’ajouter le fichier log4J.properties dans le répertoire src :

log4j.rootLogger=info, con
log4j.appender.con=org.apache.log4j.ConsoleAppender
log4j.appender.con.layout=org.apache.log4j.PatternLayout
log4j.appender.con.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

Relancez et vous verrez dans la console des traces Hibernate :

0 [main] INFO org.hibernate.cfg.annotations.Version - Hibernate Annotations 3.4.0.GA
15 [main] INFO org.hibernate.cfg.Environment - Hibernate 3.3.2.GA
...
390 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: org.h2.Driver at URL: jdbc:h2:C:/db/h2/dynaresume
390 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=sa, password=****, autocommit=true, release_mode=auto}
656 [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: H2, version: 1.0.71 (2008-04-25)
656 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: H2 JDBC Driver, version: 1.0.71 (2008-04-25)
672 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.H2Dialect
...
734 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
890 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
Hibernate: select user0_.USR_ID_N as USR1_0_0_, user0_.USR_LOGIN_C as USR2_0_0_, user0_.USR_PASSWORD_C as USR3_0_0_ from T_USER user0_ where user0_.USR_ID_N=?
User founded login=angelo (H2)
984 [main] INFO org.hibernate.impl.SessionFactoryImpl - closing
984 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - cleaning up connection pool: jdbc:h2:C:/db/h2/dynaresume

FindAllUserDynaresumeH2Hibernate (EntityManager#createQuery avec H2)

Ici nous allons créer la classe FindAllUserDynaresumeH2Hibernate qui va afficher la liste des Users de la base H2 via l’implémentation JPA Hibernate en utilisant :

EntityManager#createQuery(String qlString)

Créez la classe org.dynaresume.test.jpa.hibernate.h2.FindAllUserDynaresumeH2Hibernate comme suit :

package org.dynaresume.test.jpa.hibernate.h2;

import java.util.Collection;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.dynaresume.domain.User;

public class FindAllUserDynaresumeH2Hibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			Query query = entityManager.createQuery("select u from "
					+ User.class.getSimpleName() + " u");
			Collection<User> users = query.getResultList();
			for (User user : users) {
				System.out.println("User [id=" + user.getId() + " login=" + user.getLogin()
						+ ", password=" + user.getPassword() + "]");
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Ici nous avons utilisé la query JPA :

Query query = entityManager.createQuery("select u from " + User.class.getSimpleName() + " u");

Nous aurrions pu écrire aussi

Query query = entityManager.createQuery("from " + User.class.getSimpleName());

mais cette syntaxe ne fonctionne pas avec Eclipselink.

Lancez FindAllUserDynaresumeH2Hibernate et la console affiche la liste des User de la table T_USER de la base H2 :

...
Hibernate: select user0_.USR_ID_N as USR1_0_, user0_.USR_LOGIN_C as USR2_0_, user0_.USR_PASSWORD_C as USR3_0_ from T_USER user0_
User [id=1 login=angelo (H2), password=]
User [id=2 login=djo (H2), password=]
User [id=3 login=keulkeul (H2), password=]
User [id=4 login=pascal (H2), password=]
...

CreateUserDynaresumeH2Hibernate (EntityManager#persist avec H2)

Ici nous allons créer la classe CreateUserDynaresumeH2Hibernate qui va insérer un User dans la table T_USER de la base H2 via l’implémentation JPA Hibernate en utilisant :

EntityManager#persist(Object entity)

Créez la classe org.dynaresume.test.jpa.hibernate.h2.CreateUserDynaresumeH2Hibernate comme suit :

package org.dynaresume.test.jpa.hibernate.h2;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class CreateUserDynaresumeH2Hibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			User user = new User("jpa-user (Hibernate-H2)", "");
			entityManager.persist(user);

		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez la classe CreateUserDynaresumeH2Hibernate, mais ceci n’insère pas le User dans la base.

Ajoutez l’appel de la méthode EntityManager#flush() après l’appel de EntityManager#persist(Object o) pour forcer l’exécution de la requête SQL :

User user = new User("jpa-user (Hibernate-H2)", "");

entityManager.persist(user);
entityManager.flush();

Relancez CreateUserDynaresumeH2Hibernate et la console affiche l’erreur suivante :

Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:301)
at org.dynaresume.test.jpa.hibernate.h2.CreateUserDynaresumeH2Hibernate.main(CreateUserDynaresumeH2Hibernate.java:26)

Cette erreur s’explique par le fait que aucune transaction n’a été ouverte. Pour effectuer cela nous devons récupérer uen transaction javax.persistence.EntityTransaction et l’ourvir puis la commiter après l’insertion (EntityManager#persist(Object entity)) du User. Modifiez la classe CreateUserDynaresumeH2Hibernate comme suit :

package org.dynaresume.test.jpa.hibernate;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class CreateUserDynaresumeH2Hibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			transaction = entityManager.getTransaction();
			transaction.begin();
			
			User user = new User("jpa-user (Hibernate-H2)", "");
			entityManager.persist(user);
			
			transaction.commit();

		} catch(Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			
		}finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Vous pouvez remarquer que l’appel du flush a été omis car l’appel de EntityTransaction#commit() force l’éxécution des requêtes SQL.

Lancez CreateUserDynaresumeH2Hibernate et la console affiche :

Hibernate: insert into T_USER (USR_ID_N, USR_LOGIN_C, USR_PASSWORD_C) values (null, ?, ?)

Ce log montre que la requête SQL d’Insert dans la table T_USER a été effectué. La valeur null passé à la colonne USR_ID_N peut être déroutante, mais la valeur de cette colonne sera mis a jour en incrémentatnt le dernier ID de la table T_User (type IDENTITY). Relancez FindAllUserDynaresumeH2Hibernate et la console affiche la liste des User de la table T_USER de la base H2 avec l’utilisateur jpa-user (Hibernate-H2) :

...
Hibernate: select user0_.USR_ID_N as USR1_0_, user0_.USR_LOGIN_C as USR2_0_, user0_.USR_PASSWORD_C as USR3_0_ from T_USER user0_
User [id=1 login=angelo (H2), password=]
User [id=2 login=djo (H2), password=]
User [id=3 login=keulkeul (H2), password=]
User [id=4 login=pascal (H2), password=]
User [id=5 login=jpa-user (Hibernate-H2), password=]
...

JPA/Hibernate – Derby

Dans cette section nous allons mettre en place JPA avec Hibernate en utilisant la base de donnée Derby :

Initialisation JPA/Hibernate – Derby

JAR

Ajoutez les libraires de derby lib/derby/*.jar à votre projet.

JAR Description
lib/derby/com.springsource.org.apache.derby-10.5.1000001.764942.jar Base Derby « OSGifiée ».
lib/derby/com.springsource.org.apache.derby.client-10.5.1000001.764942.jar Client de la Base Derby « OSGifiée ».
persistence.xml

Ajoutez dans le fichier persistent.xml, la déclaration persistence-unit de derby comme suit :

<persistence-unit name="dynaresume-hibernate-derby"
		transaction-type="RESOURCE_LOCAL">

	<provider>
		org.hibernate.ejb.HibernatePersistence
	</provider>

	<class>org.dynaresume.domain.User</class>

	<properties>
		<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" />
		<property name="hibernate.connection.url" value="jdbc:derby:C:/db/derby/dynaresume" />
		<property name="hibernate.connection.username" value="" />
		<property name="hibernate.connection.password" value="" />
		<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
		<property name="hibernate.show_sql" value="true" />
	</properties>

</persistence-unit>

Voici l’explication de ces propriétés :

Nom propriété Valeur propriété Description propriété
hibernate.connection.driver_class org.apache.derby.jdbc.EmbeddedDriver Configuration du driver JDBC de la base de données Derby en mode enmbarqué.
hibernate.connection.url jdbc:derby:C:/db/derby/dynaresume Configuration de l’URL de la base de données Derby de dynaresume.
hibernate.connection.username Configuration de l’utilisateur de la base de données Derby de dynaresume.
hibernate.connection.password Configuration du mot de passe de la base de données Derby de dynaresume.
hibernate.dialect org.hibernate.dialect.DerbyDialect Dialect à utiliser pour générer les requêtes SQL pour la base de données Derby.
hibernate.show_sql true Affiche les requêtes SQL.

FindUserDynaresumeDerbyHibernate (EntityManager#find avec Derby)

Ici nous allons créer la classe FindUserDynaresumeDerbyHibernate qui va afficher le User d’ID 1 de la base Derby via l’implémentation JPA Hibernate.

Créez la classe org.dynaresume.test.jpa.hibernate.h2.FindUserDynaresumeDerbyHibernate comme suit :

package org.dynaresume.test.jpa.hibernate.h2;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class FindUserDynaresumeDerbyHibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			User user = entityManager.find(User.class, (long) 1);
			if (user == null) {
				System.out.println("User NOT founded.");
			} else {
				System.out.println("User founded login=" + user.getLogin());
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindUserDynaresumeDerbyHibernate et la console affiche le login du User d’ID 1 d’ID 1 de la table T_USER de la base Derby :

Hibernate: select user0_.USR_ID_N as USR1_0_0_, user0_.USR_LOGIN_C as USR2_0_0_, user0_.USR_PASSWORD_C as USR3_0_0_ from T_USER user0_ where user0_.USR_ID_N=?
User founded login=angelo (Derby)

FindAllUserDynaresumeDerbyHibernate (EntityManager#createQuery avec Derby)

Créez la classe org.dynaresume.test.jpa.hibernate.FindAllUserDynaresumeDerbyHibernate comme suit :

package org.dynaresume.test.jpa.hibernate.derby;

import java.util.Collection;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.dynaresume.domain.User;

public class FindAllUserDynaresumeDerbyHibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			Query query = entityManager.createQuery("select u from "
					+ User.class.getSimpleName() + " u");
			Collection<User> users = query.getResultList();
			for (User user : users) {
				System.out.println("User [id=" + user.getId() + " login="
						+ user.getLogin() + ", password=" + user.getPassword()
						+ "]");
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindAllUserDynaresumeDerbyHibernate et la console affiche la liste des User de la table T_USER de la base Derby :

...
Hibernate: select user0_.USR_ID_N as USR1_0_, user0_.USR_LOGIN_C as USR2_0_, user0_.USR_PASSWORD_C as USR3_0_ from T_USER user0_
User [id=1 login=angelo (Derby), password=]
User [id=2 login=djo (Derby), password=]
User [id=3 login=keulkeul (Derby), password=]
User [id=4 login=pascal (Derby), password=]
...

CreateUserDynaresumeDerbyHibernate (EntityManager#persist avec Derby)

Ici nous allons créer la classe CreateUserDynaresumeDerbyHibernate qui va insérer un User dans la table T_USER de la base Derby via l’implémentation JPA Hibernate.

Créez la classe org.dynaresume.test.jpa.hibernate.derby.CreateUserDynaresumeDerbyHibernate comme suit :

package org.dynaresume.test.jpa.hibernate.derby;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class CreateUserDynaresumeDerbyHibernate {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-hibernate-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			transaction = entityManager.getTransaction();
			transaction.begin();
			
			User user = new User("jpa-user (Hibernate-Derby)", "");
			entityManager.persist(user);
			
			transaction.commit();

		} catch(Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			
		}finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez CreateUserDynaresumeDerbyHibernate et la console affiche :

Hibernate: insert into T_USER (USR_ID_N, USR_LOGIN_C, USR_PASSWORD_C) values (default, ?, ?)
Hibernate: values identity_val_local()

Relancez FindAllUserDynaresumeDerbyHibernate et la console affiche la liste des User de la table T_USER de la base Derby avec l’utilisateur jpa-user (Hibernate-Derby) :

User [id=1 login=angelo (Derby), password=]
User [id=2 login=djo (Derby), password=]
User [id=3 login=keulkeul (Derby), password=]
User [id=4 login=pascal (Derby), password=]
User [id=5 login=jpa-user (Hibernate-Derby), password=]

EclipseLink est une implémentation JPA avec EclipseLink. Cette implémentation qui est basé sur les sources de TopLink est une version adaptée au contexte OSGi, ce qui le rend facilement utilisable dans un contexte Eclipse RCP. L aversion EclipseLink 2.0.0 que nous utilisons a pour objectif d’implémenter JPA 2.0 (JSR 317).

Initialisation projet org.dynaresume.test.jpa.eclipselink

Créez le projet Java org.dynaresume.test.jpa.eclipselink.

JAR

Ajoutez les JAR API JPA suivants :

JAR Description
lib/javax/com.springsource.javax.persistence-2.0.0.jar JPA API
lib/javax/com.springsource.javax.transaction-1.1.0.jar Transaction API

Ajoutez les JAR Implémentation Eclipselink suivants :

JAR Description
lib/jpa-eclipselink/org.eclipse.persistence.antlr-2.0.0.jar
lib/jpa-eclipselink/org.eclipse.persistence.asm-2.0.0.jar
lib/jpa-eclipselink/org.eclipse.persistence.core-2.0.0.jar
lib/jpa-eclipselink/org.eclipse.persistence.jpa-2.0.0.jar

Ajoutez les JAR JDBC H2

JAR Description
lib/h2/com.springsource.org.h2-1.0.71.jar Base H2 « OSGifiée ».

et JDBC Derby :

JAR Description
lib/derby/com.springsource.org.apache.derby-10.5.1000001.764942.jar Base Derby « OSGifiée ».
lib/derby/com.springsource.org.apache.derby.client-10.5.1000001.764942.jar Client de la Base Derby « OSGifiée ».

persistence.xml

Créer le fichier persistence.xml dans le répertoire src/META-INF comme suit :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">

	<persistence-unit name="dynaresume-eclipselink-h2"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.eclipse.persistence.jpa.PersistenceProvider
      	</provider>

		<class>org.dynaresume.domain.User</class>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:h2:C:/db/h2/dynaresume" />
			<property name="javax.persistence.jdbc.user" value="sa" />
			<property name="javax.persistence.jdbc.password" value="" />
			<property name="eclipselink.target-database"
				value="org.eclipse.persistence.platform.database.H2Platform" />
		</properties>

	</persistence-unit>

	<persistence-unit name="dynaresume-eclipselink-derby"
		transaction-type="RESOURCE_LOCAL">

		<provider>
			org.eclipse.persistence.jpa.PersistenceProvider
      	</provider>

		<class>org.dynaresume.domain.User</class>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:derby:C:/db/derby/dynaresume" />
			<property name="javax.persistence.jdbc.user" value="" />
			<property name="javax.persistence.jdbc.password" value="" />
			<property name="eclipselink.target-database"
				value="org.eclipse.persistence.platform.database.DerbyPlatform" />
			<property name="show-sql" value="true" />
		</properties>

	</persistence-unit>

</persistence>

Les propriétés utilisés pour le driver JDBC, l’URL… nommées javax.persistence.* sont des noms standards utilisés dans la spécification JPA 2.0 qui est implémenté par EclipseLink 2.0.0. Les anciennes versions de EclipseLink utilisaient le nommage eclipselink.*. Voici comment déclarer les propriétés avec une ancienne version de EclipseLink :

	<properties>
	<property name="eclipselink.jdbc.driver" value="org.h2.Driver" />
	<property name="eclipselink.jdbc.url" value="jdbc:h2:C:/db/h2/dynaresume" />
	<property name="eclipselink.jdbc.user" value="sa" />
	<property name="eclipselink.jdbc.password" value="" />
</properties>

REMARQUE :

  • le dialect de la base H2 org.eclipse.persistence.platform.database.H2Platform (renseigné avec la propriété eclipselink.target-database) est intégré dans la version EclipseLink 2.0.0 mais pas dans la version 1.0.1 de celle de Spring repository.
  • Je n’ai pas réussi à trouver la propriété qui permet de montrer les traces SQL (théoriquement ca devrait être show-sql, mais ca ne marche pas?).

JPA/EclipseLink – H2

Dans cette section nous allons mettre en place JPA avec Eclipselink en utilisant la base de donnée H2 :

Ici nous allons créer la classe FindUserDynaresumeH2EclipseLink qui va afficher le User d’ID 1 de la base H2 via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.h2.FindUserDynaresumeH2EclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.h2;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class FindUserDynaresumeH2Eclipselink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			User user = entityManager.find(User.class, (long) 1);
			if (user == null) {
				System.out.println("User NOT founded.");
			} else {
				System.out.println("User founded login=" + user.getLogin());
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindUserDynaresumeH2EclipseLink et la console affiche le login du User d’ID 1 d’ID 1 de la table T_USER de la base H2 :

[EL Info]: 2010-02-18 17:33:18.875--ServerSession(11587215)--EclipseLink, version: Eclipse Persistence Services - 1.1.0.r3634
[EL Info]: 2010-02-18 17:33:19.109--Not able to detect platform for vendor name [H2]. Defaulting to [org.eclipse.persistence.platform.database.DatabasePlatform]. The database dialect used may not match with the database you are using. Please explicitly provide a platform using property eclipselink.platform.class.name.
[EL Info]: 2010-02-18 17:33:19.234--ServerSession(11587215)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-h2 login successful
User founded login=angelo (H2)
[EL Info]: 2010-02-18 17:33:19.328--ServerSession(11587215)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-h2 logout successful

Ici nous allons créer la classe FindAllUserDynaresumeH2EclipseLink qui va afficher la liste des Users de la base H2 via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.h2.FindAllUserDynaresumeH2EclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.h2;

import java.util.Collection;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.dynaresume.domain.User;

public class FindAllUserDynaresumeH2EclipseLink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			Query query = entityManager.createQuery("select u from "
					+ User.class.getSimpleName() + " u");
			Collection<User> users = query.getResultList();
			for (User user : users) {
				System.out.println("User [id=" + user.getId() + " login="
						+ user.getLogin() + ", password=" + user.getPassword()
						+ "]");
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindAllUserDynaresumeH2EclipseLink et la console affiche la liste des User de la table T_USER de la base H2 :

[EL Info]: 2010-02-22 17:40:15.453--ServerSession(23414511)--EclipseLink, version: Eclipse Persistence Services - 2.0.0.v20091127-r5931
[EL Info]: 2010-02-22 17:40:15.765--ServerSession(23414511)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa/bin/_dynaresume-eclipselink-h2 login successful
User [id=1 login=angelo (H2), password=]
User [id=2 login=djo (H2), password=]
User [id=3 login=keulkeul (H2), password=]
User [id=4 login=pascal (H2), password=]
User [id=5 login=jpa-user (Hibernate-H2), password=]
[EL Info]: 2010-02-22 17:40:16.14--ServerSession(23414511)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa/bin/_dynaresume-eclipselink-h2 logout successful

Ici nous allons créer la classe CreateUserDynaresumeH2EclipseLink qui va insérer un User dans la table T_USER de la base H2 via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.h2.CreateUserDynaresumeH2EclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.h2;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class CreateUserDynaresumeH2EclipseLink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-h2";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			transaction = entityManager.getTransaction();
			transaction.begin();
			
			User user = new User("jpa-user (EclipseLink-H2)", "");
			entityManager.persist(user);
			
			transaction.commit();

		} catch(Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			
		}finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez CreateUserDynaresumeH2EclipseLink et la console affiche :

[EL Info]: 2010-02-22 17:43:17.125--ServerSession(1321194)--EclipseLink, version: Eclipse Persistence Services - 2.0.0.v20091127-r5931
[EL Info]: 2010-02-22 17:43:17.453--ServerSession(1321194)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa/bin/_dynaresume-eclipselink-h2 login successful
[EL Info]: 2010-02-22 17:43:17.546--ServerSession(1321194)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa/bin/_dynaresume-eclipselink-h2 logout successful

Relancez FindAllUserDynaresumeH2EclipseLink et la console affiche la liste des User de la table T_USER de la base H2 avec l’utilisateur jpa-user (EclipseLink-H2) :

User [id=1 login=angelo (H2), password=]
User [id=2 login=djo (H2), password=]
User [id=3 login=keulkeul (H2), password=]
User [id=4 login=pascal (H2), password=]
User [id=5 login=jpa-user (Hibernate-H2), password=]
User [id=6 login=jpa-user (EclipseLink-H2), password=]

JPA/EclipseLink – Derby

Dans cette section nous allons mettre en place JPA avec EclipseLink en utilisant la base de donnée Derby :

Ici nous allons créer la classe FindUserDynaresumeDerbyEclipseLink qui va afficher le User d’ID 1 de la base H2 via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.derby.FindUserDynaresumeDerbyEclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.derby;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class FindUserDynaresumeDerbyEclipseLink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			User user = entityManager.find(User.class, (long) 1);
			if (user == null) {
				System.out.println("User NOT founded.");
			} else {
				System.out.println("User founded login=" + user.getLogin());
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindUserDynaresumeDerbyEclipseLink et la console affiche le login du User d’ID 1 d’ID 1 de la table T_USER de la base Derby :

[EL Info]: 2010-02-18 17:42:48.5--ServerSession(19731881)--EclipseLink, version: Eclipse Persistence Services - 1.1.0.r3634
[EL Info]: 2010-02-18 17:42:49.062--ServerSession(19731881)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-derby login successful
User founded login=angelo (Derby)
[EL Info]: 2010-02-18 17:42:49.39--ServerSession(19731881)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-derby logout successful

Ici nous allons créer la classe FindAllUserDynaresumeDerbyEclipseLink qui va afficher la liste des Users de la base Derby via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.derby.FindAllUserDynaresumeDerbyEclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.derby;

import java.util.Collection;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.dynaresume.domain.User;

public class FindAllUserDynaresumeDerbyEclipseLink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			Query query = entityManager.createQuery("select u from "
					+ User.class.getSimpleName() + " u");
			Collection<User> users = query.getResultList();
			for (User user : users) {
				System.out.println("User [id=" + user.getId() + " login="
						+ user.getLogin() + ", password=" + user.getPassword()
						+ "]");
			}
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez FindAllUserDynaresumeDerbyEclipseLink et la console affiche la liste des User de la table T_USER de la base Derby :

[EL Info]: 2010-02-22 17:53:28.281--ServerSession(22543186)--EclipseLink, version: Eclipse Persistence Services - 2.0.0.v20091127-r5931
[EL Info]: 2010-02-22 17:53:28.906--ServerSession(22543186)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/_dynaresume-eclipselink-derby login successful
User [id=1 login=angelo (Derby), password=]
User [id=2 login=djo (Derby), password=]
User [id=3 login=keulkeul (Derby), password=]
User [id=4 login=pascal (Derby), password=]
User [id=5 login=jpa-user (Hibernate-Derby), password=]
[EL Info]: 2010-02-22 17:53:29.421--ServerSession(22543186)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/_dynaresume-eclipselink-derby logout successful

Ici nous allons créer la classe CreateUserDynaresumeDerbyEclipseLink qui va insérer un User dans la table T_USER de la base Derby via l’implémentation JPA Eclipselink.

Créez la classe org.dynaresume.test.jpa.eclipselink.derby.CreateUserDynaresumeDerbyEclipseLink comme suit :

package org.dynaresume.test.jpa.eclipselink.derby;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.dynaresume.domain.User;

public class CreateUserDynaresumeDerbyEclipseLink {

	public static void main(String[] args) {

		String persistentUnitName = "dynaresume-eclipselink-derby";

		EntityManagerFactory entityManagerFactory = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		try {
			entityManagerFactory = Persistence
					.createEntityManagerFactory(persistentUnitName);
			entityManager = entityManagerFactory.createEntityManager();

			transaction = entityManager.getTransaction();
			transaction.begin();
			
			User user = new User("jpa-user (EclipseLink-Derby)", "");
			entityManager.persist(user);
			
			transaction.commit();

		} catch(Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			
		}finally {
			if (entityManager != null) {
				entityManager.close();
			}
			if (entityManagerFactory != null) {
				entityManagerFactory.close();
			}
		}
	}
}

Lancez CreateUserDynaresumeDerbyEclipseLink et la console affiche :

[EL Info]: 2010-02-18 17:46:58.578--ServerSession(17447716)--EclipseLink, version: Eclipse Persistence Services - 1.1.0.r3634
[EL Info]: 2010-02-18 17:46:59.296--ServerSession(17447716)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-derby login successful
[EL Info]: 2010-02-18 17:46:59.625--ServerSession(17447716)--file:/D:/_Projets/Personal/workspace-gestcv-osgi-wordpress/step16/org.dynaresume.test.jpa.eclipselink/bin/-dynaresume-eclipselink-derby logout successful

Relancez FindAllUserDynaresumeDerbyEclipseLink et la console affiche la liste des User de la table T_USER de la base Derby avec l’utilisateur jpa-user (EclipseLink-Derby) :

User [id=1 login=angelo (Derby), password=]
User [id=2 login=djo (Derby), password=]
User [id=3 login=keulkeul (Derby), password=]
User [id=4 login=pascal (Derby), password=]
User [id=5 login=jpa-user (Hibernate-Derby), password=]
User [id=6 login=jpa-user (EclipseLink-Derby), password=]

@GeneratedValue

L’annotation JPA @GeneratedValue permet de définir la strategie d’alimentation d’un champs ID d’une table à l’aide de l’enum javax.persistence.GenerationType. Je vous conseille de lire Need a Primary Key? Let Me Show You the Ways pour en savoir plus sur cette annotation.

Il existe 2 type de stragegies pour mettre à jour un identifiant d’une table :

  • stratégie native à la base de donnée :
    • stratégie GenerationType.SEQUENCE : cette stratégie permet d’utiliser les sequences qui sont supportés par des bases de données comme comme Oracle, H2..
    • stratégie GenerationType.IDENTITY : cette stratégie permet d’utiliser le type IDENTITY (auto-incrément) qui sont supportés par des bases de données comme comme Derby, H2, SQL Server..
  • stratégie commune à toute base de donnée :
  • stratégie GenerationType.TABLE : cette stratégie consiste à créer une table qui gère les compteurs de toutes les tables de l abase de données. Cette stratégie a l’avantage de fonctionner avec n’importe quelle base mais demande 2 requête SQL (sélection+update) sur cette table lorsqu’un d’un enregistrement doit être inséré.

De ce que j’ai pu constater, la stratégie GenerationType.AUTO se comporte de la même manière que celle de GenerationType.TABLE. Dans notre cas nous avons utilisé la stratégie GenerationType.IDENTITY car (par chance) les bases de données H2 et Derby supportent le type IDENTITY. la classe User à un champs id qui est son identifiant :

[/code]

EN JPA, il n’est pas possible de pouvoir définir plusieurs stratégies dans le mapping et de « switcher » de stratégie en fonction de la base utilisé. La seule strategie commune aux 2 bases est GenerationType.TABLE qui engendre des requêtes SQL en plus.

Je pense que l’idéal est de pouvoir utiliser les solutions natives de chacune des bases (Sequence pour Oracle, Identity pour Derby) avec le MEME mapping JPA (ce qui n’est pas possible avec JPA). Je n’ai pas beaucoup étudié le sujet mais pour réaliser ceci il faudrait (peut être) pour chaque implémentation développer une classe qui permette d’effectuer un swtich de strategie selon le type de la base de donnée.

Pour Hibernate j’ai trouvé ce lien et pour EclipseLink ce lien.

Conclusion

Dans ce billet nous avons vu comment mettre en place JPA en mode « standalone » avec 2 bases de données et 2 implémentations JPA Hibernate et EclipseLink. Dans ce billet nous pouvons retenir que :

  • l’EntityManager doit être récupéré de la factory EntityManagerFactory et doit être fermé lorsqu’il n’est plus utilisé. Le code qui permet cela est redondant et l’oubli d’une fermeture d’un EntityManager peut être source de bug.
  • l’EntityTransaction qui permet de gérer les transactions doit être ouvert et fermé lorsque l’on souhaite utiliser la méthode EntityManager#persist(Object entity). Le code qui permet cela est redondant et l’oubli d’une fermeture d’un EntityTransaction peut être source de bug.
  • la définition d’un persistence-unit dans le fichier persistence.xml décrit les classes persistentes, les implémentation JPA et les informations de connections à la base. Ceci est problématique lorsque l’on souhaite définir plusieurs bases de données ou plusieurs implémentation JPA car on est obligé de dupliquer les informations. Par exemple l’élement XML class sera dupliqué dans les 4 définitions des persistance-unit (2 base * 2 implémentation JPA).

Dans le prochain billet nous verrons comment utiliser le support Spring pour JPA pour utiliser JPA dans un conteneur JPA et verrons comment Spring règle les 3 problèmes décrits ci-dessus.

Vous pouvez lire le billet suivant [step17].

Catégories :DynaResume, JPA, JPA/EclipseLink, JPA/Hibernate Étiquettes : , ,
  1. Fred
    février 19, 2010 à 1:17

    Je viens de parcourir (rapidement) toute la série d’articles et c’est une vraie mine d’or. Félicitations !

    Juste une question: quelle méthode utilises tu pour faire le build des différents bundles: PDE Build, Maven, Ant ?

  2. février 19, 2010 à 1:20

    Bonjour Fred,

    Merci pour tous tes encouragements.

    Qu’entends tu par build? Construire un product? Si c’est ca je n’ai pas encore bien étudié la question.

    Angelo

  3. Fred
    février 19, 2010 à 1:22

    Par build j’entends, en mode déploiement coté serveur, la recompilation des bundles et leur packaging pour déploiement sur Tomcat/Jetty.

    A moins que tu fasses ca manuellement pour le moment?

    • février 21, 2010 à 9:12

      Bonjour,
      sur le projet DynaResume, j’expérimente :
      1. Tycho comme système de build (fonctionne très bien).
      2. Création du fichier « plan » pour Spring DM server 2.0 à partir des bundles compilés et placés dans /repository/usr. Cela fonctionne mais je ne suis pas encore en mesure de communiquer sur le sujet car il me reste quelques tests à finaliser.

  4. février 19, 2010 à 1:28

    Je n’ai pas encore étudié la question pour gerer tout ca. Pour l’instant j’en suis au stade ou je lance mes bundles via des launch qui lance les bundles du workspace. Desole je ne peux pas t’aider sur ce sujet.

    Angelo

  5. Fred
    février 19, 2010 à 1:49

    Pas de problème, je vais devoir me pencher sur la question dans peu de temps.

    Je te conseille le livre « OSGi and Equinox: Creating Highly Modular Java™ Systems » de Jeff McAffer:

    http://www.amazon.com/OSGi-Equinox-Creating-Modular-Systems/dp/0321585712

    Il y parle de Release Engineering avec Eclipse p2

  6. février 19, 2010 à 1:51

    Merci beaucoup Fred pour cette information. La je vais finaliser ma serie de billet avec JPA+Spring puis JPA+Spring+OSGi.

  7. cyril giraudon
    février 19, 2010 à 3:20

    Bonjour,

    Ton travail est toujours aussi riche et bien documenté. Encore bravo.

    J’ai entendu parlé de weaving à propos d’Equinox & EclipseLink, c’est encore assez flou pour moi mais je crois que cela permet de placer les entity dans des bundles séparés. As-tu des informations à ce sujet ?

    Cyril.

    • février 21, 2010 à 9:17

      Bonjour,
      sur le projet DynaRésumé, les entités sont dans des bundles séparés. Hibernate nous oblige actuellement à ajouter des Import-Package inattendus et non souhaités sur la pluspart des bundles du projet. A cause notament des accès au classloader des bundles concernés.
      On peut raisonnablement espérer que cela se corrigera avec le temps et avec des produits comme equinox aspectj. Attention toutefois de ne pas faire de plan sur la comète : aujourd’hui hibernate utilise cglib pour le code enhancement et non l’AOP.

      • Fred
        février 22, 2010 à 8:37

        J’ai lu qu’Eclipselink est plus adapté pour faire du JPA sur framework OSGi mais je n’ai pas encore testé.

      • février 22, 2010 à 8:43

        En effet c’est ce que j’ai pu lire aussi. Pour l’instant je n’ai pas encore bien utilise EclipseLink dans un contexte OSGi, mais ca viendra dans les prochains billets et j’essaierai (si je comprends) de montrer son interet dans un contexte OSGi.

  8. février 19, 2010 à 3:38

    Bonjour Cyril

    Merci de tes encouragements. Je n’ai pas encore bien exploré EclipseLink avec OSGi. je dois terminer le billet avec Spring+JPA et ensuite je m’attaquerai sur JPA+Spring+OSGi avec Hibernate et EclipseLink.

    J’ai commence a mettre en place JPA/Hibernate dans un contexte OSGi et j’ai bien sue avec les problemes de classloader des proxy Hibernate. Mais la solution ne me plait pas encore car elle demande de « polluer » le bundle domain avec des import package sur les proxy hibernate. Peut etre que le weaving permettrait ca?

    Angelo

  9. Fred
    février 19, 2010 à 3:45

    Oui, j’ai lu des blogs de Martin Lippert où il parlait de cela en utilisant le projet http://www.eclipse.org/aspectj/

    Maintenant je sais que la nouvelle spec OSGi Entreprise abordera ce problème

    http://www.osgi.org/EEG/HomePage

  10. xino
    février 22, 2010 à 10:08

    Bonjour bravo pour ton travail,
    Je voudrais savoir où se trouve la partie qui fait fait que quand une donnée est changée en base les clients sont mis à jour.

    • février 23, 2010 à 8:18

      Bonjour xino,

      Merci pour tes encouragements. Je n’ai pas bien compris ta question, mais concernant la partie base de données, j’en suis qu’au debut. Dans ce billet j’ai explique JPA en « standalone ». Dans les prochains billets j’expliquerai JPA avec Spring puis JPA+Spring+OSGi ou au final le client RCP affichera la liste des User provenant de la table T_User. Concernant la mise a jour de la table via un client RCP, je ne sais pas si je vais encore traiter ce sujet. L’interet que je voies sur ce genre de sujet est d’expliquer JFace Databinding (http://wiki.eclipse.org/index.php/JFace_Data_Binding) pour binder le modele et l’UI, mais je n’ai pas encore prévu de rédiger un tel billet. Ta question était peut être plutôt comment le serveur peut il avertir le client qu’il y a eu un changement? Si c’est ca je pense que tu veux parler par exemple du Http Push (http://en.wikipedia.org/wiki/Push_technology) mais je ne sais pas du tout comment ca marche. Pour l’instant j’ai utilise « Spring Remoting HttpInvoker » pour la communication client/serveur qui est le plus basique des remoting. Je ne suis pas sur que l’on puisse gérer le « push » avec « Spring Remoting HttpInvoker ». Par contre j’ai étudié un tout petit peu ECF (http://www.eclipse.org/ecf/) qui est le framework de communication Eclipse ou l’on peut gérer beaucoup de chose (Tchat, IRC, MSN, Yahoo, Remoting services…) et j’ai développé dernièrement un support Spring pour ECF (http://wiki.eclipse.org/Using_Spring_with_ECF_Remote_Services) pour tout déclarer l’aspect remoting avec ECF. Je ne sais pas si j’ai répondu à ta question.

      • xino
        février 23, 2010 à 10:19

        Tu as bien compris ce que j’ai voulu dire.JE me suis mal exprimé.
        J’attends tes billets pour la suite.
        Je suis en train de construire un SI autour d’une appli RCP/Spring DM /OSGI /JPA (hibernate) /Mysql en suivant tes conseils.

      • février 23, 2010 à 11:30

        Tu souhaite gérer un mode à la Push HTTP? Si c’est cela le sujet nous intéresse aussi dans le projet Dynaresume. Je pensais partir sur ECF et c’est pour cela que j’ai developpe un support Spring pour ECF qui va peut etre etre integre dans la version finale d’ECF. Je ne pense pas que je parlerais tout de suite de cela. Une fois JPA terminé je pensais étudier les solutions « RCP 2 Web » pour deployer l’application RCP en mode WEB comme ce que propose RAP, Java2Script et celle de E4 (SWT for flex je croies). Mais bon il faut que je reflechisse encore a tout ca. La mon but dans un premier temps c’est de finir mes billets avec JPA+Spring+OSGi.

        Sinon je n’ai pas la science infuse et je n’ai pas beaucoup d’experience dans ce domaine RCP, Spring DM. Mes billets sont le fruit de mes etudes et Pascal Leclercq m’aide beaucoup et j’apprends un tas de truc avec lui et djo en particpant au projet dynaresume. Tout ca pour dire que si tu as des critiques à faire, n’hesites pas!

  11. février 23, 2010 à 12:51

    Bonjour Xino,
    Si ça t’ interesse, les tutos s’appuient sur le projet « DynaResume » :
    http://code.google.com/p/dynaresume/

    A ce stade, nous avons une dizaine de classes mappées en Hibernate/JPA + Spring DM+ JTA (Atomikos)+ RCP.

    La BDD par défaut est Derby.

    Si tu le souhaites tu peux récupérer le code, suivre la page « Getting Started » (http://groups.google.fr/group/dynaresume/web/getting-started) et nous faire part de tes retours.

    Tu peux également nous rejoindre sur le projet🙂.

    @+

    • xino
      février 25, 2010 à 10:23

      Merci pour les liens,
      Je suis ça avec une grande attention🙂.

      Pas de problème pour vous faire part de mes retours pour la partie http push.

  12. mars 16, 2010 à 11:51

    — Merci pour l’article ! Pour ma part j’ai montré à cette adresse http://bit.ly/a05odS que les opérations de base pour la persistance des données sont toutes identiques quelques soit l’objet à sauvegarder, les méthodes en question sont celles d’un CRUD : enregistrement (Create), lecture (Read), mise à jour (Update) et suppression (Delete).
    — La plupart du temps ces méthodes sont répétées et redéfinies dans chacun des DAO de notre application, la seule différence notable est le type des objets que ces méthodes prennent en paramètre, cependant avec Java 5 et les generics pourquoi ne pas les écrire une fois pour toutes dans un DAO générique ? cela est possible et est considéré comme une bonne pratique, la redondance des données étant à éviter à tout prix.

  1. février 18, 2010 à 5:10
  2. février 25, 2010 à 3:57

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :