我想在Hibernate 5.0.3中註冊集成器來觸發特定的EventListener。我正在修改Hibernate入門指南中提供的示例之一。最初的JUnit測試類行之有效如下:在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();
}
}
現在我只是修改這樣的設置()方法:
@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
這是我的積分級(但我不認爲這是問題的原因是安裝()的時候,我不應用集成到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
}
}
最後我的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>
非常感謝您的幫助。
你沒有離開堆棧跟蹤這麼辛苦是一定的,但我認爲問題是伴您行'StandardServiceRegistryBuilder.destroy(bootstrapServiceRegistry)'。 您正嘗試使用StandardServiceRegistryBuilder關閉類型不匹配的BootstrapServiceRegistry。 –
有問題的行是:'sessionFactory = new MetadataSources(bootstrapServiceRegistry).buildMetadata()。buildSessionFactory();'。 stacktrace是'org.eclipse.debug.core.DebugException:com.sun.jdi.ClassNotLoadedException:在檢索數組的組件類型時未發生類型加載.'和異常的原因是'org.hibernate.HibernateException: 'hibernate.dialect'未設置時,對DialectResolutionInfo的訪問不能爲空。我想這是因爲我沒有在任何地方指出hibernate.cfg.xml文件。你也對'destroy'方法是正確的。 – rocotocloc