首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >注册Hibernate 5事件监听器

注册Hibernate 5事件监听器
EN

Stack Overflow用户
提问于 2021-10-29 13:55:49
回答 1查看 35关注 0票数 0

我正在开发一个遗留的非Spring应用程序,它正在从Hibernate 3迁移到Hibernate 5.6.0。from (目前是最新的)。我通常从未在工作中使用过Hibernate事件侦听器,所以这对我来说是非常新的,我正在Hibernate 5中学习它们。

目前在一些测试类中,我们已经这样定义了Hibernate 3的代码:

代码语言:javascript
复制
protected static Configuration createSecuredDatabaseConfig()  {
    Configuration config = createUnrestrictedDatabaseConfig();
    config.setListener("pre-insert", "com.app.server.services.db.eventlisteners.MySecurityHibernateEventListener");
    config.setListener("pre-update", "com.app.server.services.db.eventlisteners.MySecurityHibernateEventListener");
    config.setListener("pre-delete", "com.app.server.services.db.eventlisteners.MySecurityHibernateEventListener");
    config.setListener("pre-load", "com.app.server.services.db.eventlisteners.EkoSecurityHibernateEventListener");
    return config;
}

这显然不再有效,我认为我需要创建一个Hibernate Integrator,我已经这样做了。

代码语言:javascript
复制
public class MyEventListenerIntegrator implements Integrator {

@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
        SessionFactoryServiceRegistry serviceRegistry) {
    EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
    
    eventListenerRegistry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(new MySecurityHibernateEventListener());
    eventListenerRegistry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(new MySecurityHibernateEventListener());
    eventListenerRegistry.getEventListenerGroup(EventType.PRE_DELETE).appendListener(new MySecurityHibernateEventListener());
    eventListenerRegistry.getEventListenerGroup(EventType.PRE_LOAD).appendListener(new MySecurityHibernateEventListener());
}

因此,现在我认为下一步是通过注册表构建器将其添加到会话中。我正在使用这个网站来帮助我:

代码语言:javascript
复制
https://www.boraji.com/hibernate-5-event-listener-example

因为我们使用的是较旧的Hibernate 3,所以我们有如下代码来创建我们的会话工厂:

代码语言:javascript
复制
protected static SessionFactory buildSessionFactory(Database db)
{
    if (db == null) {
        throw new NullPointerException("Database specifier cannot be null");
    }
    
    try {
        Configuration config = createSessionFactoryConfiguration(db);
        String url = config.getProperty("connection.url");
        String user = config.getProperty("connection.username");
        String password = config.getProperty("connection.password");           

        try {
            String dbDriver = config.getProperty("hibernate.connection.driver_class");
            Class.forName(dbDriver);
            Connection conn = DriverManager.getConnection(url, user, password);
        }
        catch (SQLException error)  {
            logger.info("Didn't find driver, on QA or production, so it's okay to assume we have DB connection");
            error.printStackTrace();
        }
        SessionFactory sessionFactory = config.buildSessionFactory();
        sessionFactoryConfigs.put(sessionFactory, config); // Cannot recover config from factory instance, must be stored.
        return sessionFactory;
    }
    catch (Throwable ex) {
        // Make sure you log the exception, as it might be swallowed
        logger.error("Initial SessionFactory creation failed.", ex);
        throw new ExceptionInInitializerError(ex);
    }
}

我上面提到的链接创建sessionfactory的方式有很大的不同。因此,我将测试它,看看它是否在我们的应用程序中工作。

没有Spring处理我们的会话和事务,在这个应用程序中,它是以Spring之前的方式手工编码的,我已经很多年没有见过这样的代码了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-11 14:02:29

我通过上面提供的链接解决了这个问题。然而,我并没有完全照搬他们所做的,但其中一些是有帮助的。我的解决方案如下:

代码语言:javascript
复制
protected static SessionFactory createSecuredDatabaseConfig() {
    Configuration config = createUnrestrictedDatabaseConfig();
    
    BootstrapServiceRegistry bootstrapRegistry =
            new BootstrapServiceRegistryBuilder()
            .applyIntegrator(new EkoEventListenerIntegrator())
            .build();
    
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(bootstrapRegistry).applySettings(config.getProperties()).build();
    
    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
    
    return sessionFactory;
}

就是这样。我尝试了多种不同的方法在没有BootstrapServiceRegistry的情况下注册事件,但这些方法都不起作用。我确实需要创建积分器。我没有包括的是以下内容:

代码语言:javascript
复制
MetadataSources sources = new MetadataSources(serviceRegistry )
              .addPackage("com.myproject.server.model");
Metadata metadata = sources.getMetadataBuilder().build();

// did not create the sessionFactory this way
sessionFactory = metadata.getSessionFactoryBuilder().build();

如果我进一步使用此方法创建sessionFactory,那么我的所有查询都会抱怨无法找到parameterName,这是另一回事。

Hibernate Integrator和这个创建sessionFactory的方法都是为了进行单元测试。如果不注册这些事件,一个单元测试就会失败,而现在它不会了,所以这就解决了我现在的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69770162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档