26 mars 2009

spring-test-context, JPA et dbUnit

Sur ma toute belle appli d'en ce moment que j'adore nous gérons la persistence avec JPA. Comme je suis un grand fan de la testabilité par POJOs (ce qui est super original de nos jours), je préconise d'utiliser spring-test-context pour tester la persistence.

Seulement, j'aime bien aussi utiliser dbUnit pour insérer des données de test prévisibles avant mes tests. Et là ça se complique sérieusement, car il faut passer à dbUnit la connexion JDBC associée à la transaction utilisée par l' EntityManager JPA (vous suivez ?)

Le problème, c'est que spring-test-context ne propose par de méthode listener au sein de la transaction (SPR-4365) ; seulement avant ou après. J'ai donc du étendre le "TransactionalTestExecutionListener" pour ajouter dans beforeTestMethod l'injection des données dbUnit.

La mauvaise surprise, c'est qu'en l'absence d'une indication explicite, Spring utilise un DefaultJpaDialect incapable d'identifier la Connection JDBC utilisée, mais ce n'est pas considéré comme un cas d'erreur donc dbUnit ne partage pas la même connexion :'(
Ajoutez à ça une connexion qui est par défaut en autocommit, des tables Oracle AQ$TRUC qui viennent pourrir les données de test et ça vous donne une idée de mes trois derniers jours :-/

Pour résumer, si vous voulez faire comme moi :
  • N'oubliez pas de préciser le jpaVendorAdapter (HibernateJpaVendorAdapter) dans la définition Spring de votre entityManagerFactory
  • Utilisez DataSourceUtils pour récuperer la connexion associée à la transaction JPA en cours
et là, miracle, ça marche enfin :)

Etape suivante : faire un merge à la volée entre les deux persistence.xml qui vont constituer mon contexte JPA (SPR-2598), le permier étant "mutualisé" avec une autre application ... 


4 commentaires:

JJ a dit…

Hi Nicolas!

You may also find this little adapter of use:
http://code.google.com/p/springdbunit/

It is also getting added to dbUnit, based on dev list conversation:
http://sourceforge.net/tracker/?func=detail&aid=2587755&group_id=47439&atid=449494

Nicolas De Loof a dit…

Thanks a lot for the link ;)
Nice to see better support for spring-test context in DBUnit

damien.gouyette a dit…

Avec quelques exemples de codes succints, cela serait un chouya plus parlant !

Nicolas De Loof a dit…

Je m'en doute mais le code en question n'est pas "libre de droit", et j'ai déjà subi quelques remontrances sur ma liberté d'expression dans ses pages :-/