jeudi 23 avril 2009

[GUIDE] Migration Hibernate4GWT => Gilead

**** for english version see below ****

Bonjour,

Au début de mon projet je suis parti sur la librairie Hibernate4GWT afin d'utiliser de manière simple Hibernate dans le cadre de mon projet perso GWT / SmartGWT.
(Vous noterai que je ne donne pas trop de détails sur ce fameux projet perso, j'en suis désolé mais je préfère ne pas donner trop de détails tant que le projet n'est pas abouti).

Pour rappel ou info : l'utilité principale de l'outil Hibernate4GWT (ainsi que Gilead) est de rendre transparent à l'utilisateur la transformation des collections à rendre persistentes.
Pour faire simple : si vous utilisez la lib classique d'Hibernate, vous allez avoir des soucis de cast lorsque vous aurez à rendre persistent des collections : en effet, Hibernate possède ses propres implémentations des objets de collection Java : PersistentSet pour l'interface Set et PersistentList pour l'interface List
Or GWT ne connaît pas ces objets et par conséquent refuse de les sérialiser. Un peu embètant n'est-ce pas ?

Du coup, Hibernate4GWT et Gilead permettent de mapper ces objets Hibernate spécifiques en objets java plus classiques (ArrayList, HashSet, etc.) et de les rendre sérializables !! Alléluia !!

Maintenant vous comprenez l'utilité de l'outil. Voyons désormais comment procéder pour migrer de l'ancienne version de la lib (nommée Hibernate4Gwt) à la nouvelle version, plus riche et performante (nommée Gilead).

Voici les étapes à passer (ces étapes s'appliquent au mode stateless qui est le mode par défaut, pour les autres modes, je vous laisse le soin d'adapter ce guide en fonction)
Ce guide est plus détaillé que celui qui est publié dans la FAQ du site officiel.

1 - Télécharger la dernière version de Gilead ici :
http://sourceforge.net/project/showfiles.php?group_id=239931

2 - Dézipper la dans le répertoire lib de votre application

3 - Sous Eclipse faites un refresh de votre répertoire lib

4 - Supprimer les libs suivantes du classpath de votre projet :
  • hibernate4gwt-1.1.2.jar
  • beanlib-3.3.0beta20b.jar
  • beanlib-hibernate-3.3.0beta20b.jar
  • hibernate-entitymanager.jar
5 - Rajouter les libs suivantes dans votre projet (elles se trouvent toutes dans des sous-répertoires du dossier Gilead que vous avez dézippé) :
  • adapter-core.jar
  • hibernate-util.jar
  • adapter4gwt.jar
  • beanlib-3.3.0beta21c.jar
  • beanlib-hibernate-3.3.0beta21c.jar

Je vous conseille également de rajouter l'ensemble des lib contenues dans chaque répertoire de Gilead (sauf bien entendu les libs adapter4blazeds et adapter-actionscript qui ne concernent pas les projets GWT).

6 - Dans vos objets de domaines remplacez les implements LazyPojo par implements LightEntity

Et remplacez dans vos Services côté serveur les implements HibernateRemoteService par implements PersistentRemoteService

7 - Mettez à jour votre HibernateUtil afin d'initialiser votre BeanManager.
Pour faire simple je vous donne mon propre code, à vous d'adapter le vôtre. C'est assez simple.

public class MyHibernateUtil {

private static final SessionFactory sessionFactory;

private static PersistentBeanManager beanManager;

static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure()
.buildSessionFactory();
HibernateUtil hibernateUtil = new HibernateUtil();
hibernateUtil.setSessionFactory(sessionFactory);

beanManager = new PersistentBeanManager();
beanManager.setPersistenceUtil(hibernateUtil);
beanManager.setProxyStore(new StatelessProxyStore());

} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

public static PersistentBeanManager getBeanManager() {
return beanManager;
}

}
8 - Dans votre fichier .gwt.xml, remplacez les lignes suivantes :
  • inherits name="net.sf.hibernate4gwt.Hibernate4Gwt15" par
    inherits name="net.sf.gilead.Adapter4Gwt15"

  • generate-with class="net.sf.hibernate4gwt.rebind.Gwt15ProxyGenerator" par
    generate-with class="net.sf.gilead.proxy.gwt.Gwt15ProxyGenerator"

Et voilà !! C'en est terminé de cette migration. Enjoy !! ;)

A+

************************************
****** ENGLISH VERSION ********
************************************

Hello,

At the beginning of my project I used the library Hibernate4GWT to use Hibernate in a simple way in my personal GWT / SmartGWT project.
(You will note that I do not give too many details on this famous personal project, I'm sorry but I prefer not to give too many details until the project is over and available on the web).

Reminder : The main usefulness of the Hibernate4GWT tool (and Gilead) is to make transparent to the user the process of making collections persistent.
Simply put: if you use the classic lib Hibernate, you will have serialization issues with collections: in fact, Hibernate has its own implementations of Java collection objects: PersistentSet for Set interface and PersistentList for List interface.
But GWT does not recognize these objects and therefore refuses to serialize them. A little annoying is not it?

So Hibernate4GWT and Gilead allow to map these Hibernate specific objects with classic java objects (ArrayList, HashSet, etc.) and make them serializable! Alleluia!

Now you understand the usefulness of the tool. So let's see how to migrate from the older version of the lib (Hibernate4Gwt) to the new version, more rich and powerful (Gilead).

Here are the steps to follow. These steps apply to stateless mode (which is the default mode), for other modes, I'll leave it to you to adapt this guide (just take a look on the FAQ of the Gilead website : http://noon.gilead.free.fr/gilead/index.php?page=f-a-q to check the class name you have to replace)
This guide is more detailed than the one published in the FAQ of the Gilead web site.

1 - Download the latest version of Gilead here:
http://sourceforge.net/project/showfiles.php?group_id=239931

2 - Unzip it in the lib directory of your application

3 - On Eclipse do a refresh of your lib directory

4 - Delete the following libs in your project classpath:
  • hibernate4gwt-1.1.2.jar
  • beanlib-3.3.0beta20b.jar
  • beanlib-hibernate-3.3.0beta20b.jar
  • hibernate-entitymanager.jar
5 - Add the following libs in your project (they are all located in subdirectories of the Gilead folder that you unzipped):
  • adapter-core.jar
  • hibernate-util.jar
  • adapter4gwt.jar
  • beanlib-3.3.0beta21c.jar
  • beanlib-hibernate-3.3.0beta21c.jar
I suggest you also add all the libs that are on the Gilead folder (exceptadapter4blazeds et adapter-actionscript that do not concern GWT projects).

6 - In your domain object classes, replace implements LazyPojo by implements LightEntity

And replace in your server-side service implements HibernateRemoteService by implements PersistentRemoteService

7 - Update your HibernateUtil to initialize your BeanManager.
Simply put, I give you my own code, I let you adapt it to yours. It's quite simple.


public class MyHibernateUtil {

private static final SessionFactory sessionFactory;

private static PersistentBeanManager beanManager;

static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure()
.buildSessionFactory();
HibernateUtil hibernateUtil = new HibernateUtil();
hibernateUtil.setSessionFactory(sessionFactory);

beanManager = new PersistentBeanManager();
beanManager.setPersistenceUtil(hibernateUtil);
beanManager.setProxyStore(new StatelessProxyStore());

} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

public static PersistentBeanManager getBeanManager() {
return beanManager;
}

}
8 - in your .gwt.xml file, replace the following lines :
  • inherits name="net.sf.hibernate4gwt.Hibernate4Gwt15" by
    inherits name="net.sf.gilead.Adapter4Gwt15"

  • generate-with class="net.sf.hibernate4gwt.rebind.Gwt15ProxyGenerator" by
    generate-with class="net.sf.gilead.proxy.gwt.Gwt15ProxyGenerator"

And that's it for the migration !! Enjoy !!

Bye

Bonjour

*** for english version see below ***

Bienvenue sur ce blog.

Actuellement je travaille en parallèle au boulot sur un projet perso.
Il s'agit d'une appli basée sur GWT / SmartGWT / Hibernate. Le tout développé sous Eclipse.

Dans le cadre de ce dévéloppement j'ai été amené à rencontrer certains obstacles.
Donc pourquoi ne pas en faire profiter tout le monde.

Voilà donc le pourquoi de la création de ce blog sur lequel je tacherai de publier des articles concernant GWT, Hibernate et l'ensemble des outils que j'ai pu utiliser durant le développement.

En vous souhaitant donc une bonne lecture et en espérant que ça puisse vous aider

A++

**********************************************
*********** ENGLISH VERSION ***************
**********************************************

Welcome on board ladies and gentlemen

Currently I'm working, besides my real job, on an application based on GWT / SmartGWT / Hibernate. I'm using Eclipse to develop it.

During the development phase I have encountered multiple of issues / obstacles.
So why not sharing my troubles and my solutions with everyone ?
Yep. This blog is here for.

I will try to post sometimes new articles / guides focused on GWT / SmartGwt, Hibernate and all the other tools I have used during the development phase.

Thank you

Bye