Logo_Hibernate
logo ehcache

Il est fréquent d’utiliser Ehcache pour améliorer les performances d’une application basée sur Hibernate.
Ehcache est d’ailleurs très efficace et plutôt facile à mettre en place (je ferais peut-être un article) mais il est facile de tomber dans le piège suivant : Mettre en cache une collection issue d’un mapping LAZY hibernate.

Voici un exemple :

@Entity
@Table(name = "T_TEAM")
public class Team implements Serializable {
 ...
 @OnetoMany(fetch = FetchType.LAZY, ...)
 private List<User> members;
 ...
}

L’objet Team possède une relation @OneToMany vers User, cette relation est LAZY car je n’ai pas toujours besoin de récupérer les membres de l’équipe.

@Service
public class MyServiceImpl implements MyService {

 @Cacheable(cacheName = "...")
 public Team findTeam(...) {
  return dao.findTeam(...);
 }

}

Le résultat de la recherche d’une équipe selon certains critères ne change jamais, on annote donc la méthode @Cacheable. Cela signifie que lors de prochains appels (avec les mêmes paramètres) on retournera la valeur stockée en cache.

Attention : l’objet Team mis en cache ne contiendra pas la liste des membre car cette dernière est LAZY. Si dans une autre transaction de l’application on récupère cet objet et que l’on souhaite travailler directement sur les membres on aura la fameuse LazyInitializationException !

Je n’ai pour le moment pas de solution propre pour contourner ce problème :

  • Soit je met toute la grappe en cache
  • Soit je détache l’objet de la session manuellement avant qu’elle soit stockée en cache
  • Soit j’arrête de mettre en cache ces objets
Publicités