0

我正在尝试在 Hibernate 5.0.3 中注册一个集成器以触发特定的 EventListener。我正在修改 Hibernate Getting Started Guide 中提供的示例之一。运行良好的原始 jUnit 测试类如下:

    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();
        }
    }

现在我只需像这样修改 setUp() 方法:

@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 );
        }
    }

当我执行测试用例时,出现以下错误:

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

这是我的 Integrator 类(但我认为这不是问题,因为当我不将 Integrator 应用于 BootstrapServiceRegistryBuilder 时,setUp() 方法也会失败):

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

    }
}

最后是我的 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>

非常感谢您的帮助。

4

1 回答 1

3

好的,解决了:

    @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  );
    }
}
于 2015-11-06T12:02:40.257 回答