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

时间:2014-02-15 18:13:01

标签: java spring hibernate jpa

我有一个Hibernate拦截器,我想把它放在Hibernate的onLoad()调用上。我这样做是因为我希望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;
    }
}

2 个答案:

答案 0 :(得分:1)

我这样做了:

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;
    ...
}

答案 1 :(得分:0)

我放弃了使用一些基于hibernate特定事件的解决方案的方法,而是去使用在Spring中需要aspectJ的@Configuration。

请参阅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注释标记一个类符合条件   弹簧驱动的配置。在最简单的情况下,它可以使用   作为标记注释: