19.6. Moniteur de performance

L'optimisation n'est pas d'un grand intérêt sans le suivi et l'accès aux données de performance. Hibernate fournit toute une panoplie de rapport sur ses opérations internes. Les statistiques dans Hibernate sont fournies par SessionFactory.

19.6.1. Suivi d'une SessionFactory

Vous pouvez accéder au métriques d'une SessionFactory de deux manières. La première option est d'appeler sessionFactory.getStatistics() et de lire ou d'afficher les Statistics vous même.

Hibernate peut également utiliser JMX pour publier les métriques si vous activez le MBean StatisticsService. Vous pouvez activer un seul MBean pour toutes vos SessionFactory ou un par factory. Voici un code qui montre un exemple de configuration minimaliste :

// MBean service registration for a specific SessionFactory
Hashtable tb = new Hashtable();
tb.put("type", "statistics");
tb.put("sessionFactory", "myFinancialApp");
ObjectName on = new ObjectName("hibernate", tb); // MBean object name

StatisticsService stats = new StatisticsService(); // MBean implementation
stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
server.registerMBean(stats, on); // Register the Mbean on the server
// MBean service registration for all SessionFactory's
Hashtable tb = new Hashtable();
tb.put("type", "statistics");
tb.put("sessionFactory", "all");
ObjectName on = new ObjectName("hibernate", tb); // MBean object name

StatisticsService stats = new StatisticsService(); // MBean implementation
server.registerMBean(stats, on); // Register the MBean on the server

TODO: Cela n'a pas de sens : dans le premier cs on récupère et on utilise le MBean directement. Dans le second, on doit fournir le nom JNDI sous lequel est retenu la fabrique de session avant de l'utiliser. Pour cela il faut utiliser hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")

Vous pouvez (dés)activer le suivi pour une SessionFactory

  • au moment de la configuration en mettant hibernate.generate_statistics à false

  • à chaud avec sf.getStatistics().setStatisticsEnabled(true) ou hibernateStatsBean.setStatisticsEnabled(true)

Les statistiques peuvent être remises à zéro de manière programmatique à l'aide de la méthode clear() Un résumé peut être envoyé à un logger (niveau info) à l'aide de la méthode logSummary()

19.6.2. Métriques

Hibernate fournit un certain nombre de métriques, qui vont des informations très basiques aux informations très spécialisées qui ne sont appropriées que dans certains scenarii. Tous les compteurs accessibles sont décrits dans l'API de l'interface Statistics dans trois catégories :

  • Les métriques relatives à l'usage général de la Session comme le nombre de sessions ouvertes, le nombre de connexions JDBC récupérées, etc...

  • Les métriques relatives aux entités, collections, requêtes et caches dans leur ensemble (métriques globales),

  • Les métriques détaillées relatives à une entité, une collection, une requête ou une région de cache particulière.

Par exemple, vous pouvez vérifier l'accès au cache ainsi que le taux d'éléments manquants et de mise à jour des entités, collections et requêtes et le temps moyen que met une requête. Il faut faire attention au fait que le nombre de millisecondes est sujet à approximation en Java. Hibernate est lié à la précision de la machine virtuelle, sur certaines plateformes, cela n'offre qu'une précision de l'ordre de 10 secondes.

Des accesseurs simples sont utilisés pour accéder aux métriques globales (e.g. celles qui ne sont pas liées à une entité, collection ou région de cache particulière). Vous pouvez accéder aux métriques d'une entité, collection, région de cache particulière à l'aide de son nom et à l'aide de sa représentation HQL ou SQL pour une requête. Référez vous à la javadoc des APIS Statistics, EntityStatistics, CollectionStatistics, SecondLevelCacheStatistics, and QueryStatistics pour plus d'informations. Le code ci-dessous montre un exemple simple :

Statistics stats = HibernateUtil.sessionFactory.getStatistics();

double queryCacheHitCount  = stats.getQueryCacheHitCount();
double queryCacheMissCount = stats.getQueryCacheMissCount();
double queryCacheHitRatio =
  queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);

log.info("Query Hit ratio:" + queryCacheHitRatio);

EntityStatistics entityStats =
  stats.getEntityStatistics( Cat.class.getName() );
long changes =
        entityStats.getInsertCount()
        + entityStats.getUpdateCount()
        + entityStats.getDeleteCount();
log.info(Cat.class.getName() + " changed " + changes + "times"  );

Pour travailler sur toutes les entités, collections, requêtes et régions de cache, vous pouvez récupérer la liste des noms des entités, collections, requêtes et régions de cache avec les méthodes : getQueries(), getEntityNames(), getCollectionRoleNames(), et getSecondLevelCacheRegionNames().