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

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

问题描述:

我有一个Hibernate拦截器,我想把它放在Hibernate的onLoad()调用上。我这样做是因为我想让一个JPA实体在Spring中注入一个SecureRandom实例。由于JPA上下文和Spring上下文不混合,这是从Spring上下文到JPA上下文的桥梁。如何在Spring 3的Java配置中连接我的Hibernate 4拦截器?

我在我的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; 
    } 
} 

我放弃了使用某些基于hibernate特定事件的解决方案的方法,而是使用了@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 包含注释驱动的方面,该方面利用此功能允许依赖注入任何对象。该支持旨在将 用于在任何容器的控制之外创建的对象。 域对象通常属于此类别,因为它们通常是使用新运算符以编程方式创建的 ,或者是由数据库查询的结果以ORM工具创建的 。

@Configurable注释标记一个类为合格的 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; 
    ... 
}