Les interceptors d'Hibernate permettent d'intervenir au niveau des opérations réalisées au niveau des entités. La capture ci-dessous permet de voir la liste des méthodes qu'il est possible de surcharger :




Dans le cas qui nous intéresse, nous allons surcharger la méthode onPrepareStatement(String) sur un héritage de la classe EmptyInterceptor d'Hibernate car c'est à cet endroit qu'il est possible de modifier à la volée les requêtes réalisées par Hibernate sur l'entité.
En supposant que le schéma de l'environnement est connu par l'intermédiaire d'une propriété système Java "env" (ex: -Denv=SCHEMA_PROD), on peut alors à l'exécution remplacer à la volée le nom du schéma par le schéma d'environnement uniquement pour l'objet Etat, c'est à dire pour l'entité pointant sur la table ETAT. Dans toute la requête SQL fabriquée par Hibernate, on aura alors remplacé tous les MON_SCHEMA.ETAT par SCHEMA_PROD.ETAT.

import org.hibernate.EmptyInterceptor;

public class SchemaInterceptor extends EmptyInterceptor {

@Override
public String onPrepareStatement(String sql) {
String pstmt = super.onPrepareStatement(sql);
String schema = System.getProperty("env");
if( pstmt.matches("MON_SCHEMA.ETAT")) {
pstmt = pstmt.replaceAll("MON_SCHEMA.ETAT", schema + ".ETAT");
}
return pstmt;
}
}
Ensuite, il faut intégrer l'intercepteur dans la sessionFactory Hibernate (contexte Spring) :

<bean id="schemaInterceptor" class="fr.openfarm.hibernate.interceptors.SchemaInterceptor"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">...</property>
...
<property name="entityInterceptor">
<ref bean="schemaInterceptor"/>
</property>
</bean>

Attention : on ne peut déclarer qu'un seul intercepteur par session.
Les sources ci-dessous donnent d'autres exemples d'utilisation des intercepteurs (audit des entités ou la sécurité) :