gpt4 book ai didi

java - 如何测试LazyInitializationException?

转载 作者:行者123 更新时间:2023-12-01 04:37:35 25 4
gpt4 key购买 nike

我有一些代码(在生产中):

  • 在一个线程中,使用数据库中的数据填充缓存
  • 在另一个线程中,从缓存中获取数据,并开始迭代其属性。

这引发了LazyInitializationException

虽然我知道如何解决该问题,但我想对此进行测试。但是我不知道如何在测试的正确部分重新创建异常。

我必须用一些测试数据填充数据库,因此我的测试用@Transactional注释。如果不这样做会导致设置失败...您猜对了...LazyInitializationException

这是我当前的测试:

@Transactional
public class UpdateCachedMarketPricingActionTest extends AbstractIntegrationTest {

@Autowired
private UpdateCachedMarketPricingAction action;

@Autowired
private PopulateMarketCachesTask populateMarketCachesTask;

@Test @SneakyThrows
public void updatesCachedValues()
{

// Populate the cache from a different thread, as this is how it happens in real life
Thread updater = new Thread(new Runnable() {
@Override
public void run() {
populateMarketCachesTask.populateCaches();
}
});
updater.start();
updater.join();

updateMessage = {...} //ommitted

action.processInstrumentUpdate(updateMessage);
}

因此,我在一个单独的线程中启动缓存,尝试将其移出当前的 @Transaction 范围。此外,我还在缓存底漆内调用 entityManager.detatch(entity),以尝试确保缓存中存在的实体无法延迟加载其集合。

但是,测试通过了...没有抛出异常。

如何强制让实体进入某种状态,当我下次尝试迭代它的集合时,它将抛出 LazyInitializationException

最佳答案

您需要确保每个操作的事务都已提交,并且彼此独立。使用@Tranactional注释您的测试方法或测试类会使当前测试事务保持打开状态,然后在执行整个测试后将其回滚。

因此,一种选择是执行以下操作:

@Autowired
private PlatformTransactionManager transactionManager;


@Test
public void example() {
new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {

@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// add your code here...
}
});
}

您可以在其自己的回调中调用第一个操作,然后在不同的回调中调用第二个操作。然后,当您在回调后访问 Hibernate 或 JPA 实体时,这些实体将不再附加到当前工作单元(例如 Hibernate Session)。因此,此时访问惰性集合或字段将导致 LazyInitializationException

问候,

山姆

附:请注意,这种技术自然会将更改提交到您的数据库。因此,如果您需要清理修改后的状态,请考虑在 @AfterTransaction 方法中手动执行此操作。

关于java - 如何测试LazyInitializationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17122955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com