Pascalleclercq's Blog

05/05/2010

Accédez à des Entités en remoting malgré Hibernate

Filed under: Hibernate,Spring — pascalleclercq @ 9:39

Si vous utilisez hibernate vous savez sans nul doute qu’il est founit mécanisme de Proxy afin de gérer le fameux « lazy loading ».

Les Proxy hibernate nous sont donc bien utiles dans un grand nombre de cas mais si vous souhaitez exposer vos Entités en remoting, alors ces Proxy deviennent subitement bien encombrants.

Comment ?

La problématique n’est pas nouvelle et des Frameworks tels que BeanLib sont apparus pour résoudre cette problématique. A la demande générale je vais présenter l’approche retenue dans le projet DynaRésumé.

Quand ?

A mes yeux, le meilleur moment pour dé-proxyfier vos entités hibernate c’est le moment où vos beans s’apprêtent à quitter la VM. En effet, couper les entités de la session hibernate trop tôt peut se réveler particulièrement contre productif.
Si vous avez la chance d’utiliser Spring  (je ne connais aucune bonne raison de ne pas l’utiliser) la réponse tient en une petite classe Java et un peu de XML.

D’abord il nous faut créer un « Interceptor » qui va nous permettre d’ajouter du comportement aux appels remoting de manière non-intrusive.

import net.sf.beanlib.hibernate.HibernateBeanReplicator;
import net.sf.beanlib.hibernate3.Hibernate3BeanReplicator;
import net.sf.beanlib.hibernate3.LazyHibernateCustomBeanTransformer;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class EntityCleanerInterceptor implements MethodInterceptor {

	private final HibernateBeanReplicator replicator = new Hibernate3BeanReplicator()
			.initCustomTransformerFactory(new LazyHibernateCustomBeanTransformer.Factory());;

	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object fromBean = invocation.proceed();

		Object toBean = replicator.copy(fromBean);

		return toBean;
	}
}

Puis, nous allons brancher notre Interceptor à notre « Service Exporter« , ici un « HttpInvokerServiceExporter ».

	<bean id="entityCleanerInterceptor "
		class="org.dynaresume.springremoting.EntityCleanerInterceptor " />

<bean name="/MyRemoteService"
		class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
		<property name="service" ref="myService" />
		<property name="serviceInterface" value="org.dynaresume.core.service.MyService" />
		<property name="interceptors">
			<list>
				<ref bean="entityCleanerInterceptor " />
			</list>
		</property>
	</bean>

Et voilà !!!! Avouez que l’on peut difficilement faire plus simple.

A noter qu’au sein du projet DynaResume, nous avons eu l’occasion de mettre en oeuvre cette technique dans un contexte OSGi sans effort particulier en dehors de la « bundle-ization » des jars « BeanLib ».

A ce jour, je n’ai pas enore eu l’occasion de tester Gilead mais si un lecteur a des retours ou est tenté par l’expérience je suis preneur d’informations : Les commentaires sont toujours le bienvenus.

3 commentaires »

  1. Merci beaucoup ! J’ai quasiment perdu une journée à cause de ce problème.

    Commentaire par Ahingsaka — 07/05/2010 @ 7:48 | Répondre

  2. Merci😀

    Commentaire par Cyril — 07/05/2010 @ 8:29 | Répondre


RSS feed for comments on this post. TrackBack URI

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

Propulsé par WordPress.com.

%d blogueurs aiment cette page :