Blogounage

Aller au contenu | Aller au menu | Aller à la recherche

Mot clé - hibernate

Fil des billets - Fil des commentaires

dimanche 13 juillet 2008

How to retrieve the Hibernate Session from the EntityManager interface

Well, as I myself fell into this stupid gap, I guess I'll try to help. I was quite pushed in this trap by a fallacious part of the jboss documentation :

@PersistenceContext EntityManager entityManager;
public void someMethod();
{
  org.jboss.ejb3.entity.HibernateSession hs = (HibernateSession)entityManager;
  org.hibernate.Session session = hs.getHibernateSession();
}

Let's be clear : this is totally WRONG! Yes, it will work under JBoss, but as there's a standard way to do this, this is not the right way to do this.

In fact, there's a dedicated method that lets you retrieve the underlying persistence manager : EntityManager.getDelegate(). If you read this method's javadoc, you'll see the following :

/**
 * Return the underlying provider object for the EntityManager,
 * if available. The result of this method is implementation
 * specific.
 * @throws IllegalStateException if this EntityManager has been closed.
 */

public Object getDelegate();

And the "underlying provider", for Hibernate, is obviously the Hibernate Session instance...

So, the right way to retrieve the Session is something like the following instead :

@PersistenceContext EntityManager entityManager;
public void someMethod();
{
  org.hibernate.Session session = (Session)entityManager.getDelegate();
}

Under JBoss, using this code won't make a big difference. But using the standard way will let you run your code under several appservers (namely, it works like a charm[1] under JBoss 4.2.2.ga and Glassfishv2ur1 for example). If you use the bad way above, this will just crash under Glassfish, for example...

I reported the corresponding documentation bug in the JBOSS tracker.

Hope this helps...

Notes

[1] ça, c'est pour Seb

mardi 24 juin 2008

Quelques déclarations XSD ou DTD de formats XML connus

C'est le genre de chose qu'il est sympathique d'avoir écrit en tête de ce type de fichier pour disposer de l'auto-complétion XML dans son IDE favori. Lorsque j'utilise un nouveau format XML, la première chose que je cherche est en effet à ajouter cet entête pour me faciliter la vie (et aux autres une fois commité :)).

Note : dans la liste ci-dessous, je ne mets pas le prologue XML pour gagner en concision. Toutefois, ça ne fait jamais de mal de le mettre. Personnellement j'essaie de le mettre systématiquement.

Hibernate : mappings hbm.xml

Même s'il vaut mieux à mon avis passer aux annotations lorsqu'on en a la possibilité, voici une déclaration de DTD qui fonctionne chez moi pour ceux qui ont encore des mappings hibernate à la sauce XML :

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="net.batmat.domaine">
...
</hibernate-mapping>

Java Persistence : persistence.xml

Pour ceux qui utilisent Java Persistence, cette "sous-spécification" des EJB3 devenue une spécification autonome dans sa version 2 :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
                http://java.sun.com/xml/ns/persistence
                http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"

        version="1.0">

...
</persistence>

Spring : fichier de contexte XML

Depuis la version 2, ils ont subdivisé leur format XML en différents namespaces. Voici un exemple fonctionnel qui met en œuvre un certain nombre de ces espaces de nommages XML. Je laisse en exercice le passage à Spring 2.5 (que nous utilisons, d'ailleurs, mais on n'a pas mis à jour le XML) ou l'ajout d'un autre namespace dont vous auriez besoin :-).

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                http://www.springframework.org/schema/util
                http://www.springframework.org/schema/util/spring-util-2.0.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>

...
</beans>

Maven : pom.xml

Celui-là, il est sacrément pratique vu la taille du truc :

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/maven-v4_0_0.xsd"
>

...
</project>

Voilà déjà pour cette fois. Une fois cet entête ajouté, dans Eclipse par exemple, tapez juste "<" quelque part et vous verrez la liste des balises apparaître et leur documentation si les auteurs l'ont indiquée (après qu'Eclipse ait pu récupérer le XSD sur Internet, bien sûr) : Auto-complétion du XML avec Eclipse

Si vous en avez d'autres, n'hésitez pas à les poster (ou à les demander, si je suis dans un bon jour) dans les commentaires.

Update 01/10/2008, ajout du application.xml des EAR :

<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" 
     "http://java.sun.com/dtd/application_1_3.dtd">

<application id="mon appli">
...
</application>

lundi 14 mai 2007

Toplink better than Hibernate?

Today, we received Oracle. They were coming to speak about their business Intelligence offer, Oracle Application Server and so on.

When speaking about Toplink, the guy said something like: "We could say Toplink is kind of a father to Hibernate. Obviously, it's already almost 15 years of existence." Well, why not. Though I didn't see any article interviewing Gavin King confirming that, but apart from reusing their ideas or not, Toplink was here before, OK.

The assertion that surprised me was another one, something like: As Toplink is older than Hibernate, it's obviously more robust and has more functions.

Well, I'm not sure I would agree with this one. In fact, as Toplink Essentials was only released in the OpenSource world very recently (may 2006 in Glassfish, so the JPA implementation even more, if I'm right), and experts seems to agree that about 90% of the projects today use Hibernate for the persistance layer (Didier Girard says it in the TV4IT Webcast. I think this is more of a feeling for him, so if anybody has some statistics about, I'm very interested. I should also ask Sami Jaber for his feeling about it.).

Webcast (in french, see about 9/10 of the video for the Hibernate is 90% of the current projects) :

So, what is the right indicator about software robustness?

Is this the software that's been released fifteen years ago, used by 10 people around the word since this time, or is this this other one, that's been released 6 years ago, used by 90 people since then? Who was the most testable? The one that only few people could download to give it a try, or the one that's been downloaded and tested tons of time by a lot different people?

In my opinion, but I also agree I only know Hibernate, I'm pretty sure Hibernate has already been thoroughly tested. At least, as much as Toplink has. My point is that the maturing of Hibernate was a lot quicker than Toplink's one. Once more, it would be very interesting to put numbers in the debate. Hibernate has been opensourced since its start, so it always benefited from code reviews, patches and so on, and evolved very quickly.

To sum up, because of the fundamental differences between both development styles, I'm not sure that today Hibernate is still behind Toplink speaking about robustness, functions scope and so on. Though I'd be delighted to learn about interesting differences, if you know about it.

mardi 2 janvier 2007

Différence entre Session.save() et Session.persist()

Dans la version 3 d'Hibernate, d'un point de vue strictement utilitaire, il y a deux méthodes qui ont le même objectif : sauvegarder un objet en base (ou le rendre persistant, comme on dit).

Le problème est donc de savoir laquelle il faudrait plutôt utiliser. Et bien la réponse est simple, euuuu...

Traduction de ce qu'on peut lire dans la FAQ :

Je ne sais pas si je dois utiliser save() ou persist().

Ces deux méthodes rendent persistante une instance éphémère (NdT : transient). Toutefois, la méthode persist() ne garantit pas que la valeur de l'identifiant sera assignée immédiatement, l'assignement pourrait arriver au moment du flush.

La méthode persist() garantit aussi qu'aucun INSERT ne sera exécuté si elle est appelée en dehors d'un contexte transactionnel. Ceci est utile pour les conversations longues avec un contexte de persistance/session étendu.

La méthode save() ne garantit pas la même chose. Elle retourne un identifiant, et si un INSERT doit être exécuté pour obtenir l'identifiant it returns an identifier (e.g. générateur "identity", pas "sequence"), cet INSERT arrive immédiatement, peu importe que vous soyez à l'intérieur ou à l'extérieur d'une transaction. Ce n'est pas bon pour les conversations longues avec un contexte de persistance/session étendu

En résumé, si vous faites des conversations longues, utilisez plutôt persist(). Sinon il y a peu de différence, mis à part toutefois le cascading. Celui-ci n'est propagé dans le cas de save() que si la relation est mappée cascade="save-update", alors que c'est cascade="persist" pour persist().

Notez que si vous mappez cascade="all", cela inclue à la fois save-update et persist. Donc pour les relations mappées "all", la sémantique de persist() et de save() sont à mon avis extrêmement proches.

dimanche 24 décembre 2006

Mapping Hibernate pour routeur...

Extraordinaire :-).

vendredi 15 décembre 2006

Java Persistence with Hibernate

Il y a quelques semaines, j'ai vu passer ce billet sur le blog de l'équipe de développement d'Hibernate. Étant donné que j'avais "suffisamment", sans prétention aucune, contribué au forum d'Hibernate pour participer, j'ai immédiatement envoyé un mail à l'adresse indiquée. J'ai mis un descriptif très très court de mon expérience sur l'outil, tellement j'étais stressé d'avoir une chance de faire partie des heureux bénéficiaires et donc pressé d'avoir envoyé le mail :-).

Je n'ai eu aucune nouvelle pendant environ une semaine, je ne savais absolument pas s'il y avait eu 25 personnes avant moi ou pas, puis j'ai reçu le 5 décembre ce mail de la part de Christian Bauer :

A copy of 'Java Persistence with Hibernate' is on its way to you. Inside the US Manning expects to get the book to you this week, to Europe and other countries it might take more than a week.

If there is any problem with the delivery please contact me directly.

Thank you again for contributing to Hibernate.

Et la page récapitulative a été mise à jour :-).

Bon, je me suis dit : Je n'en parle pas tant que ce n'est pas définitif. Pis finalement, je suis allé récupérer ça à la poste ce matin :

800 pages, il va me falloir un peu de temps avant d'éventuellement pouvoir reparler du contenu :-).