当前位置: 首页 > 知识库问答 >
问题:

如何将springrepo注入hibernate拦截器

雷晋
2023-03-14

我们正在构建一个应用程序,我们需要将实体更新登录到历史表中。我试图通过Hibernate拦截器来实现这一点,我们可以设法获得所有的更改,但很难将它们插入审计表。

我的JPA配置

public class JPAConfiguration {
 ----
 @Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws SQLException {
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPackagesToScan(new String[] {"com.yyy.persist"});

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setShowSql(true);
    // thsi is required in order to enable Query DSL
    vendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");
    factoryBean.setJpaVendorAdapter(vendorAdapter);
   // factoryBean.setMappingResources(mappingResources);
    // adding hibernate interceptor

    Properties jpaProperties = new Properties();
    jpaProperties.setProperty("hibernate.ejb.interceptor", "com.yyy.admin.service.AuditInterceptor");
    factoryBean.setJpaProperties(jpaProperties);
    return factoryBean;
}

我的拦截器

public class AuditInterceptor extends EmptyInterceptor {
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
        String[] propertyNames, Type[] types) {

     if ( entity instanceof Auditable ) {
    // updates++;

    for (int i = 0; i < propertyNames.length; i++) {

        if ((currentState[i] == null && previousState[i] != null)
                || (currentState[i] != null && previousState[i] == null) || (currentState[i] != null
                        && previousState[i] != null && !currentState[i].equals(previousState[i]))) {

            AuditLog audit = new AuditLog();
            audit.setAction("UPDATE");
            audit.setFieldChanged(propertyNames[i]);
            audit.setOldvalue(previousState[i] != null ? previousState[i].toString() : "");
            audit.setNewvalue(currentState[i] != null ? currentState[i].toString() : "");
            audit.setTimeStamp(new Date());
            audit.setUsername(userName);

            entities.add(audit);
        }
    }

    // iterate elements on the report build a entity
 }
    return false;
}

public void afterTransactionCompletion(Transaction tx) {

    if (tx.wasCommitted()) {
if (entities != null) {
            for (AuditLog e : entities) {
                System.out.println(e);
                //.save(e);
            }
            entities = new ArrayList<AuditLog>();
        }
    }
     }

}

在方法afterTransactionCompletion中,我需要将所有审计实体写入DB,Autowire不工作,因为这不是spring管理的bean,是否有任何方法可以在此方法中获取DB会话,以便我可以执行插入。?

共有2个答案

桓瀚
2023-03-14

我知道这有点晚了,但也许对其他人有帮助。通过使用Spring bean而不是类名作为"hibernate.ejb.interceptor"的值,hibernate使用Spring bean而不是实例化一个新类。

更多信息可以在这里找到:自动装备到Hibernate拦截器

国晟睿
2023-03-14

将Springbean注入非Spring托管类的典型解决方案是通过静态资源持有者。例如,您有一个名为StaticServiceHolder的类,annotate is with@Component,然后通过setter为要注入的Springbean创建静态字段。比如:

@Component
public class StaticServiceHolder
{
    public static AuditService auditService;

    @Autowired
    public void setAuditService(AuditService auditService)
    {
        StaticServiceHolder.auditService = auditService;
    }
}

或者,如果需要注入大量这些内容,则可以自动连接ApplicationContext。这样你就可以得到任何你需要的豆子。

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        ApplicationContextHolder.applicationContext = ctx;
    }
}

....
//in your hibernate interceptor
YourAuditService auditService = ApplicationContextHolder.applicationContext.getBean(YourAuditService.class);
auditService.saveAuditLog();

无论哪种方式,只要您使用的服务是Transactional,您都应该能够将您的内容保存在DB中。希望这对你有用。

对于事务管理器设置:

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf)
{
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    return transactionManager;
}
 类似资料:
  • 问题内容: 我正在使用一个已定义的拦截器,我想从拦截器中通过DAO层进行db调用,所以我如何将Spring bean注入到struts拦截器中。是否可以将spring bean注入到struts拦截器中,任何人都可以提出任何想法在此。 问题答案: 编辑 由于不需要将拦截器声明为Spring bean,因此删除了不必要的部分。感谢@AleksandrM对其进行测试。 就像使用Actions一样,(如

  • 问题内容: 对于像老兄一样工作的安全系统(例如受监视的强制访问控制),我们必须拦截并处理hibernate生成的所有选择语句。我们将用户,时间戳和sql选择存储在数据库中,以使用其他工具进行某些性能分析。这些信息可以确定用户尝试查看的内容。对于选择语句,准备好的属性很有价值。我们需要完整的SQL语句,包括所有参数。 是否有任何侦听器或拦截器可以加入并处理所有这些事情?迄今为止最大的突出问题是语句参

  • 拦截注册表 bp RegOpenKey(A) 打开子健 bp RegOpenKeyEx 打开子健 bp RegQueryValue(A) 查找子健 bp RegQueryValueEx 查找子健 bp RegSetValue(A) 设置子健 bp RegSetValueEx(A) 设置子健

  • 问题内容: 如何在Hibernate拦截器中获取Hibernate会话? 我正在尝试使用Hibernate通过组织ID透明地强制执行数据访问。我设置了一个全局筛选器,以按组织ID筛选所有查询。现在,在保存/更新之前,我需要使用实体拦截器在所有实体上设置组织ID。 组织ID来自HttpSession 我已经在Hibernate会话中将Organizational Id设置为Filter属性,我想在我

  • 问题内容: 我尝试了一些来自hibernate 4.0拦截器的 代码,该代码为使用会话级拦截器提供了以下代码: 但是,我同时检查了hibernate-core 4.0源代码和onliehibernate 4.0 java- doc ,该类没有方法,但是hibernate 3.6 java- doc确实具有此方法。 有人知道该方法移到哪里吗?如果已弃用,为什么文档仍将其保留在教程文档中?在4.0中如

  • 问题内容: 我正在尝试为AngularJS应用编写HTTP拦截器以处理身份验证。 这段代码有效,但是我担心手动注入服务,因为我认为Angular应该自动处理此问题: 我刚开始做的事情,但是遇到了循环依赖问题: 我担心的另一个原因是Angular Docs中$ http上 的部分似乎显示了一种将依赖项注入“常规方式”到Http拦截器中的方法。请参阅“拦截器”下的代码段: 上面的代码应该放在哪里? 我