如何在Spring Data中修改Hibernate Interceptor

时间:2017-07-01 07:19:45

标签: hibernate spring-data

我有自定义的Hibernate Interceptor实现,但是我想使用依赖项:

class MyInterceptor extends EmptyInterceptor {
 private Handler handler;
 public void setHandler(Handler) {
    this.handler = handler;
 }

 @Override
 pubic boolean onFlushDirty(...) {
   handler.customLogic
 } 


}

我想像这样做:

   SessionImplementor sessionImplementor = (SessionImplementor) em.unwrap(Session.class);
   MyInterceptor interceptor = (MyInterceptor)sessionImplementor.getInterceptor();
   interceptor.setHandler(any custom handler implementation);

但是我正在使用Spring Data,我想对许多Spring Data存储库有这种行为。

我尝试使用JpaRepositoryFactoryBeanCommonRepository

@Transactional(readOnly = true)
@Repository
public class CommonTransactionalRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CommonTransactionalRepository<T, ID> {

  private final EntityManager em;

  @Autowired
  Handler handler;

  @PostConstruct
  public void init() {
    SessionImplementor sessionImplementor = (SessionImplementor) em.unwrap(Session.class);
    MyInterceptor interceptor = sessionImplementor.getInterceptor();
    interceptor.setHandler(handler);
  }

  public CommonTransactionalRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager em) {
    super(entityInformation, em);
    this.em = em;
  }

public class CommonJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {

  @Override
  protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
    return new CommonRepositoryFactory<>(em);
  }

  private static class CommonRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {

    private final EntityManager em;

    public CommonRepositoryFactory(EntityManager em) {
      super(em);
      this.em = em;
    }

    @SuppressWarnings("unchecked")
    protected Object getTargetRepository(RepositoryMetadata metadata) {
      JpaEntityInformation entityInformation = getEntityInformation(metadata.getDomainType());
      return new CommonTransactionalRepositoryImpl(entityInformation, em);
    }

    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
      return CommonTransactionalRepositoryImpl.class;
    }
  }

}

但没有运气,@ PostConstruct不起作用,显然因为@PostConstruct在创建代理之前工作,它不能与@Transactional一起使用。

1 个答案:

答案 0 :(得分:0)

你可以覆盖EntityManagerFactory或者假设只有一个ApplicationContext涉及拦截器内部的那个并从中获取所需的bean。