2015-11-05 1 views
0

J'essaie d'enregistrer un intégrateur dans Hibernate 5.0.3 pour déclencher un EventListener particulier. Je modifie l'un des exemples fournis dans le Guide de démarrage d'Hibernate. La classe de test JUnit original qui fonctionne bien est la suivante:Ajout d'un intégrateur dans Hibernate 5.0.3

package org.hibernate.tutorial.annotations; 

    import java.util.Date; 
    import java.util.List; 

    import org.hibernate.Session; 
    import org.hibernate.SessionFactory; 
    import org.hibernate.boot.MetadataSources; 
    import org.hibernate.boot.registry.BootstrapServiceRegistry; 
    import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; 
    import org.hibernate.boot.registry.StandardServiceRegistry; 
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 

    import junit.framework.TestCase; 

    /** 
    * Illustrates the use of Hibernate native APIs. The code here is unchanged from the {@code basic} example, the 
    * only difference being the use of annotations to supply the metadata instead of Hibernate mapping files. 
    * 
    * @author Steve Ebersole 
    */ 
    public class AnnotationsIllustrationTest extends TestCase { 
     private SessionFactory sessionFactory; 

     @Override 
     protected void setUp() throws Exception { 
      // A SessionFactory is set up once for an application!   
      final StandardServiceRegistry registry = new StandardServiceRegistryBuilder() 
        .configure() // configures settings from hibernate.cfg.xml 
        .build(); 
      try { 
       sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); 
      } 
      catch (Exception e) { 
       // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory 
       // so destroy it manually. 
       StandardServiceRegistryBuilder.destroy(registry); 
      } 
     } 

     @Override 
     protected void tearDown() throws Exception { 
      if (sessionFactory != null) { 
       sessionFactory.close(); 
      } 
     } 

     @SuppressWarnings({ "unchecked" }) 
     public void testBasicUsage() { 
      // create a couple of events... 
      Session session = sessionFactory.openSession(); 
      session.beginTransaction(); 
      session.save(new Event("Our very first event!", new Date())); 
      session.save(new Event("A follow up event", new Date())); 
      session.getTransaction().commit(); 
      session.close(); 

      // now lets pull events from the database and list them 
      session = sessionFactory.openSession(); 
      session.beginTransaction(); 
      List result = session.createQuery("from Event").list(); 
      for (Event event : (List<Event>) result) { 
       System.out.println("Event (" + event.getDate() + ") : " + event.getTitle()); 
      } 
      session.getTransaction().commit(); 
      session.close(); 
     } 
    } 

Maintenant, je modifie simplement la méthode setUp() comme ceci:

@Override 
    protected void setUp() throws Exception { 
     // A SessionFactory is set up once for an application! 
     BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().applyIntegrator(new MyEventListenerIntegrator()).build(); 

     try { 
      sessionFactory = new MetadataSources(bootstrapServiceRegistry).buildMetadata().buildSessionFactory(); 
     } 
     catch (Exception e) { 
      // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory 
      // so destroy it manually. 
      StandardServiceRegistryBuilder.destroy(bootstrapServiceRegistry); 
     } 
    } 

Lorsque j'exécute le cas de test, je reçois l'erreur suivante:

java.lang.ClassCastException: org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl cannot be cast to org.hibernate.boot.registry.internal.StandardServiceRegistryImpl 

C'est ma classe intégrateur (mais je ne pense pas que ce soit le problème, car la méthode setUp() échoue aussi quand je ne demande pas l'intégrateur à l'BootstrapServiceRegistryBuilder):

package org.hibernate.tutorial.annotations; 

import org.hibernate.boot.Metadata; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.engine.spi.SessionFactoryImplementor; 
import org.hibernate.event.service.spi.EventListenerRegistry; 
import org.hibernate.event.spi.EventType; 
import org.hibernate.integrator.spi.Integrator; 
import org.hibernate.service.spi.SessionFactoryServiceRegistry; 

public class MyEventListenerIntegrator implements Integrator { 

    public void integrate(
      Configuration configuration, 
      SessionFactoryImplementor sessionFactory, 
      SessionFactoryServiceRegistry serviceRegistry) { 
     // As you might expect, an EventListenerRegistry is the thing with which event listeners are registered It is a 
     // service so we look it up using the service registry 
     final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class); 

     //  3) This form adds the specified listener(s) to the end of the listener chain 
     eventListenerRegistry.appendListeners(EventType.LOAD, new LoadListenerExample()); 
    } 

    @Override 
    public void disintegrate(SessionFactoryImplementor arg0, SessionFactoryServiceRegistry arg1) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void integrate(Metadata arg0, SessionFactoryImplementor arg1, SessionFactoryServiceRegistry arg2) { 
     // TODO Auto-generated method stub 

    } 
} 

Et enfin mon hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?> 
<!-- 
    ~ Hibernate, Relational Persistence for Idiomatic Java 
    ~ 
    ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later. 
    ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. 
    --> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 

    <session-factory> 

     <!-- Database connection settings --> 
     <property name="connection.driver_class">org.h2.Driver</property> 
     <property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property> 
     <property name="connection.username">sa</property> 
     <property name="connection.password"></property> 

     <!-- JDBC connection pool (use the built-in) --> 
     <property name="connection.pool_size">1</property> 

     <!-- SQL dialect --> 
     <property name="dialect">org.hibernate.dialect.H2Dialect</property> 

     <!-- Disable the second-level cache --> 
     <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> 

     <!-- Echo all executed SQL to stdout --> 
     <property name="show_sql">true</property> 

     <!-- Drop and re-create the database schema on startup --> 
     <property name="hbm2ddl.auto">create</property> 

     <!-- Names the annotated entity class --> 
     <mapping class="org.hibernate.tutorial.annotations.Event"/> 

    </session-factory> 

</hibernate-configuration> 

Merci beaucoup pour votre aide.

+0

Vous n'avez pas quitté le stacktrace si difficile d'être certain, mais je suppose que le problème est avec votre ligne 'StandardServiceRegistryBuilder.destroy (bootstrapServiceRegistry)'. Vous essayez d'utiliser le StandardServiceRegistryBuilder pour fermer un BootstrapServiceRegistry qui est une incompatibilité de type. –

+0

La ligne problématique est: 'sessionFactory = new MetadataSources (bootstrapServiceRegistry) .buildMetadata(). BuildSessionFactory();'. La piletrace est 'org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: le type n'a pas été chargé lors de la récupération du type de composant de array.' et la cause de l'exception est' org.hibernate.HibernateException: L'accès à DialectResolutionInfo ne peut pas être nul lorsque 'hibernate.dialect' n'est pas défini. Je suppose que c'est parce que je n'indiquais pas le fichier hibernate.cfg.xml n'importe où. Vous avez également raison sur la méthode 'destroy'. – rocotocloc

Répondre

3

Ok, résolu:

@Override 
protected void setUp() throws Exception { 
    // A SessionFactory is set up once for an application! 
    BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().applyIntegrator(new MyEventListenerIntegrator()).build(); 

    final StandardServiceRegistry registry = new StandardServiceRegistryBuilder(bootstrapServiceRegistry) 
      .configure() // configures settings from hibernate.cfg.xml 
      .build(); 
    try { 
     sessionFactory = new MetadataSources(registry ).buildMetadata().buildSessionFactory(); 
    } 
    catch (Exception e) { 
     // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory 
     // so destroy it manually. 
     StandardServiceRegistryBuilder.destroy(registry ); 
    } 
} 
+0

Je voulais mentionner une autre option qui consiste à utiliser le mécanisme de découverte de service de Java (http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html) qu'Hibernate prend en charge pour la découverte des intégrateurs et autres points d'extension. –

+0

Merci pour votre aide, je vais essayer. – rocotocloc