我正在尝试手动连接Spring Data JPA对象,以便我可以生成DAO代理(也称为存储库) - 而无需使用Spring bean容器.
不可避免地,我会被问到为什么要这样做:这是因为我们的项目已经在使用Google Guice(并且在使用Gin和GWT的UI上),我们不想维护另一个IoC容器配置,或者拉入所有产生的依赖关系.我知道我们可以使用Guice SpringIntegration,但这是最后的选择.
似乎所有东西都可用于手动连接对象,但由于它没有很好地记录,我现在遇到了困难.
根据Spring Data用户指南,可以单独使用存储库工厂.不幸的是,该示例显示了RepositoryFactorySupport哪个是抽象类.经过一番搜索,我找到了JpaRepositoryFactory
JpaRepositoryFactory实际上工作得很好,除了它不会自动创建交易.必须手动管理事务,否则任何内容都不会持久保存到数据库:
entityManager.getTransaction().begin();
repositoryInstance.save(someJpaObject);
entityManager.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)
问题原来是@Transactional注释没有自动使用,需要一个帮助TransactionInterceptor
值得庆幸的是,JpaRepositoryFactory在返回之前,可以进行回调以向生成的Repository代理添加更多AOP建议:
final JpaTransactionManager xactManager = new JpaTransactionManager(emf);
final JpaRepositoryFactory factory = new JpaRepositoryFactory(emf.createEntityManager());
factory.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory) {
factory.addAdvice(new TransactionInterceptor(xactManager, new AnnotationTransactionAttributeSource()));
}
});
Run Code Online (Sandbox Code Playgroud)
这是事情进展不顺利的地方.单步执行代码中的调试器,TransactionInterceptor确实创建了一个事务 - 但错误EntityManager.Spring EntityManager通过查看当前正在执行的线程来管理活动.这样TransactionInterceptor做并看到EntityManager线程没有活动绑定,并决定创建一个新线程.
但是,这个new EntityManager与创建并传递给JpaRepositoryFactory构造函数的实例不同,后者需要一个EntityManager.问题是,我如何制作TransactionInterceptor …