Question

J'ai défini hibernate.generate_statistics = true et je dois maintenant enregistrer les mbeans pour que je puisse voir les statistiques dans la console jmx. Il me semble que je ne peux aller nulle part et que cela ne semble pas être un problème aussi difficile. Je complique peut-être les choses, mais dans tous les cas, j’ai essayé:

  • J'ai copié EhCacheProvider et l'ai instancié avec une version étendue de CacheManager surchargée init () et appelée ManagementService.registerMBeans (...) après l'initialisation. Le code fonctionnait bien jusqu'à l'appel de registerMBeans (...), ce qui entraînerait l'échec de l'initialisation du fournisseur avec une erreur générique (malheureusement, je ne l'ai pas écrit.) Cette approche était motivée par les méthodes utilisées dans cette visite virtuelle sur les performances de la durée de vie.
  • J'ai créé mon propre MBean avec une méthode de démarrage qui exécutait un code similaire à Cet exemple d’enregistrement de mbeans jmx d’ehcache . Tout semblait fonctionner correctement et mon mbean apparaît dans la console jmx mais rien pour net.sf.ehcache.
  • J'ai depuis mis à niveau ehcache vers la version 1.5 (nous utilisions la version 1.3, je ne sais pas si cela est spécifique à jboss 4.2.1 ou simplement quelque chose que nous avons choisi nous-mêmes) et je suis passé à l’utilisation de SingletonEhCacheProvider et à la saisie manuelle des statistiques au lieu de traitant de l'enregistrement mbean. Cela ne s'est pas vraiment mieux passé cependant; Si j'appelle getInstance (), le CacheManager renvoyé n'a qu'une copie de StandardQueryCache, mais les journaux jboss indiquent que de nombreux autres caches ont été initialisés (un pour chacune des entités mises en cache de notre application.)

EDIT: Eh bien, j’ai compris une chose ... la connexion via JConsole révèle les statistiques mbeans. J'imagine que ManagementFactory.getPlatformMBeanServer () ne vous donne pas le même serveur mbean que celui utilisé par jboss. Quoi qu'il en soit, il semble que je rencontre un problème similaire à celui que j'ai eu lorsque j'ai essayé de collecter les statistiques manuellement, car je reçois tous les zéros même après avoir cliqué un instant sur mon application.

Était-ce utile?

La solution 2

Résolu. Comme je ne voyais pas toutes les caches de mes entités, je soupçonnais que je ne recevais pas l'instance SessionFactory appropriée. J'ai commencé avec cette ligne (voir l'exemple de code d'enregistrement jmx dans le lien que j'ai fourni dans la question):

SessionFactory sf = (new Configuration()).configure().buildSessionFactory();

Le résultat final a été que le gestionnaire de cache avec lequel je me suis retrouvé était une nouvelle instance et non celle du contexte de persistance. J'ai donc essayé de refactoriser comme:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
return ((EntityManagerFactoryImpl)emf).getSessionFactory();

mais qui vient de lancer une exception (je ne me souviens pas du texte exact; quelque chose qui a pour effet de "ne peut pas initialiser le contexte de persistance".) Il ne reste donc plus d'autre option, j'ai ajouté un bean sans état (UtilMgr ) à mon application et laisser persistence injecter le correct SessionFactory. Voici ce haricot:

import javax.ejb.Stateless;
import javax.persistence.PersistenceUnit;
import net.sf.ehcache.CacheManager;
import org.hibernate.SessionFactory;

@Stateless
public class UtilMgrBean implements UtilMgr {
    // NOTE: rename as necessary
    @PersistenceUnit(unitName = "myPersistenceCtx")
    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return this.sessionFactory;
    }

    public CacheManager getCacheManager() {
        return CacheManager.getInstance(); // NOTE: assumes SingletonEhCacheProvider
    }
}

et voici le code corrigé de la procédure mentionnée précédemment:

try {
    // NOTE: lookupBean is a utility method in our app we use for jndi lookups.
    //   replace as necessary for your application.
    UtilMgr utilMgr = (UtilMgr)Manager.lookupBean("UtilMgrBean", UtilMgr.class);
    SessionFactory sf = utilMgr.getSessionFactory();
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

    // NOTE: replace myAppName as necessary
    ObjectName on = new ObjectName("Hibernate:type=statistics,application=myAppName");

    // Enable Hibernate JMX Statistics
    StatisticsService statsMBean = new StatisticsService();
    statsMBean.setSessionFactory(sf);
    statsMBean.setStatisticsEnabled(true);
    mbs.registerMBean(statsMBean, on);

    CacheManager cacheMgr = utilMgr.getCacheManager();
    ManagementService.registerMBeans(cacheMgr, mbs, true, true, true, true);
} catch(Throwable t) {
    throw new RuntimeException(t);
}

Vous pouvez également utiliser cette méthode getCacheManager () de UtilMgr si vous souhaitez récupérer les statistiques manuellement (ce que je ferai probablement de toute façon.) Vous pouvez trouver plus d'informations sur l'utilisation des objets Cache et Statistics dans les exemples de code ehcache.

Si quelqu'un peut me renseigner sur une méthode de recherche statique de la fabrique de sessions sans qu'il soit nécessaire de créer ce bean de session supplémentaire, j'aimerais l'entendre.

Autres conseils

La réponse ci-dessus suppose que SingletonEhcacheProvider est utilisé et qu'il a également besoin du bean utilmgr, cette autre solution utilise un bean de démarrage et ne fait pas l'hypothèse de singleton

.
@Name("hibernateStatistics")
@Scope(ScopeType.APPLICATION)
@Startup
public class HibernateUtils {
@In
private EntityManager entityManager;

@Create
public void onStartup() {
    if (entityManager != null) {
        try {
            //lookup the jboss mbean server
            MBeanServer beanServer = org.jboss.mx.util.MBeanServerLocator.locateJBoss();
            StatisticsService mBean = new StatisticsService();
            ObjectName objectName = new ObjectName("Hibernate:type=statistics,application=<application-name>");
            try{
                beanServer.unregisterMBean(objectName);
            }catch(Exception exc) {
                //no problems, as unregister is not important
            }
            SessionFactory sessionFactory = ((HibernateSessionProxy) entityManager.getDelegate()).getSessionFactory();
            mBean.setSessionFactory(sessionFactory);
            beanServer.registerMBean(mBean, objectName);

            if (sessionFactory instanceof SessionFactoryImplementor ){
                CacheProvider cacheProvider = ((SessionFactoryImplementor)sessionFactory).getSettings().getCacheProvider();
                if (cacheProvider instanceof EhCacheProvider)  {
                    try{
                        Field field = EhCacheProvider.class.getDeclaredField("manager");
                        field.setAccessible(true);
                        CacheManager cacheMgr = (CacheManager) field.get(cacheProvider);
                        ManagementService.registerMBeans(cacheMgr, beanServer, true, true, true, true);
                    }catch(Exception exc) {
                        //do nothing
                        exc.printStackTrace();
                    }
                }
            }

        } catch (Exception e) {
            throw new RuntimeException("The persistence context " + entityManager.toString() + "is not properly      configured.", e);
        }
    }
 }

}

Nous utilisons MbeanServerLocator car jboss mbean serait le deuxième serveur mbean dans des environnements tels que linux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top