Java 如何测试在“POST_COMMIT_INSERT”回调上执行的事务性工作
我在调试和诊断应用程序中的问题时遇到困难 我有一个JPA事件监听器,用于执行POST_COMMIT_插入中的工作。执行的工作也是事务性的 我在编写捕获事务后事务中发生的工作的测试时遇到困难 我当前的测试在@PostTransaction方法中执行它的断言。然而,尽管我看到数据是使用log语句持久化的,但事务后的工作对我来说是不可用的 我怀疑这是因为在我的@PostTransaction方法中,我仍然太早了,而且还有另一个事务正在进行中 下面的示例大致演示了该场景: 创建并保存Foo后,创建并保存一个条 在此场景中,我看到以下输出: 信息:已创建栏:1 但测试失败了 我的@AfterTransaction是在错误的交易后运行的假设是正确的,还是这里有其他错误 如果是,我该如何测试 我曾尝试在酒吧工厂中移动@Transaction边界,但没有任何效果Java 如何测试在“POST_COMMIT_INSERT”回调上执行的事务性工作,java,spring,hibernate,unit-testing,transactions,Java,Spring,Hibernate,Unit Testing,Transactions,我在调试和诊断应用程序中的问题时遇到困难 我有一个JPA事件监听器,用于执行POST_COMMIT_插入中的工作。执行的工作也是事务性的 我在编写捕获事务后事务中发生的工作的测试时遇到困难 我当前的测试在@PostTransaction方法中执行它的断言。然而,尽管我看到数据是使用log语句持久化的,但事务后的工作对我来说是不可用的 我怀疑这是因为在我的@PostTransaction方法中,我仍然太早了,而且还有另一个事务正在进行中 下面的示例大致演示了该场景: 创建并保存Foo后,创建并保存
// Step 1. The factory that responds to creation of the Foo, and build a bar.
@Component
class BarFactory implements PostInsertEventListener
{
// Note: I've tried various versions of @Transactional on different points
// within this class, and none have worked.
@Autowired
private BarRepository repository;
@Override
public void onPostInsert(PostInsertEvent event)
{
if (event.getEntity() instanceof Foo)
{
createBar();
}
}
@Transactional
public createBar()
{
Bar bar = new Bar();
repository.save(bar);
log.info("Bar was created: " + bar.getId());
}
}
// Step 2: Register the BarFactory
@Component
class LifecycleListenerFactory {
// This is a spring bean, and the listeners are also spring beans
// so we have to use a somewhat long-winded approach to register them
// with the EntityManager
@Autowired
public LifecycleListenerFactory(EntityManager em, BarFactory barFactory)
{
SessionFactory sessionFactory = getSessionFactory(em);
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
EventListenerGroup<PostInsertEventListener> eventListenerGroup = registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT);
eventListenerGroup.appendListener(barFactory);
}
SessionFactory getSessionFactory(EntityManager entityManager) {
Session session = (Session) entityManager.getDelegate();
SessionFactory sessionFactory = session.getSessionFactory();
return sessionFactory;
}
}
// Step 3: Test.
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TransactionConfiguration(defaultRollback=false)
class MyTest {
@Autowired
private FooRepository fooRepo;
@Autowired
private BarRepository barRepo;
@Test
public void test()
{
fooRepo.save(new Foo());
}
@AfterTransaction
public void assert()
{
assertThat(barRepo.findAll().size(),equalTo(1));
}
}