繁体   English   中英

如何在Spring 3的Java配置中连接Hibernate 4拦截器?

[英]How do I hook up my Hibernate 4 interceptor in Java configuration for Spring 3?

我有一个Hibernate拦截器,我想在它的onLoad()调用中加入Hibernate。 我这样做是因为我希望JPA实体具有一个由Spring注入到其中的SecureRandom实例。 由于JPA上下文和Spring上下文没有混合使用,因此这是从Spring上下文到JPA上下文的桥梁。

我在Java配置中有“两个地方”,在这里我为Hibernate 4设置了东西。 据此( https://jira.springsource.org/browse/SPR-8940 ),我认为要以编程方式设置Hibernate拦截器,我需要访问LocalSessionFactoryBean。 也许通过LocalContainerEntityManagerFactoryBean? 我只是不知道该怎么做,或者是否需要重新配置设置Hibernate内容的方式。 任何帮助将非常感激!

@Bean
JpaTransactionManager jpaTransactionManager(LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean) {
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(localContainerEntityManagerFactoryBean.getObject());
    return jpaTransactionManager;
}

@Bean(name = "LocalContainerEntityManagerFactory")
@Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(BasicDataSource jdbcConnection) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    localContainerEntityManagerFactoryBean.setDataSource(jdbcConnection);
    localContainerEntityManagerFactoryBean.setPackagesToScan(this.getClass().getPackage().getName());

    Properties jpaProperties = new Properties();
    jpaProperties.setProperty("hibernate.hbm2ddl.auto", "create");
    localContainerEntityManagerFactoryBean.setJpaProperties(jpaProperties);
    HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    hibernateJpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
    hibernateJpaVendorAdapter.setShowSql(true);
    localContainerEntityManagerFactoryBean.setJpaVendorAdapter(hibernateJpaVendorAdapter);
    return localContainerEntityManagerFactoryBean;
}


@Component
public class InvitationEntityInterceptor extends EmptyInterceptor {
    @Autowired
    SecureRandom secureRandom;
    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if(entity instanceof Invitation) {
            Invitation invitation = (Invitation) entity;
            invitation.setRandom(secureRandom);
        }
        return false;
    }
}

我已经这样处理:

Spring数据库配置类:

@Bean
@DependsOn("hibernateInterceptor")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource,
        JpaVendorAdapter jpaVendorAdapter,
        HibernateInterceptor hibernateInterceptor) {

    LocalContainerEntityManagerFactoryBean emfb =
            new LocalContainerEntityManagerFactoryBean();
    ...
    Properties props = new Properties();
    props.put("hibernate.ejb.interceptor", hibernateInterceptor);
    emfb.setJpaProperties(props);
    return emfb;
}

Hibernate拦截器类:

@Component
public class HibernateInterceptor extends EmptyInterceptor {
    ...
    @Autowired
    private MyRepository myRepository;
    ...
}

我放弃了使用某些基于休眠特定事件的解决方案的方法,而是使用了@Configuration,它在Spring中需要AspectJ。

参见http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/aop.html

9.8.1使用AspectJ通过Spring依赖注入域对象

Spring容器实例化并配置在您的应用程序上下文中定义的bean。 给定包含要应用的配置的Bean定义的名称,也可以要求Bean工厂配置一个预先存在的对象。 spring-aspects.jar包含注释驱动的方面,该方面利用此功能允许依赖项注入任何对象。 该支撑旨在用于在任何容器的控制范围之外创建的对象。 域对象通常属于此类,因为它们通常是使用new运算符或通过数据库查询的结果通过ORM工具以编程方式创建的。

@Configurable批注将一个类标记为适用于Spring驱动的配置。 在最简单的情况下,它可以用作标记注释:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM