我有自定义的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存储库有这种行为。
我尝试使用JpaRepositoryFactoryBean
和CommonRepository
:
@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一起使用。
答案 0 :(得分:0)
你可以覆盖EntityManagerFactory
或者假设只有一个ApplicationContext
涉及拦截器内部的那个并从中获取所需的bean。