spring-boot - 使用多个数据源的 LazyInitializationException
问题描述
当我尝试在 spring-boot 上使用多个数据源时,我面临着一个巨大的问题。我的问题是因为我使用的是 spring 批处理并且我没有足够的权限来从我的生产数据库上的 spring-batch 创建 METADATA 表所以我需要使用例如 H2 来创建这些表,但是当我尝试在我的工作处理器中加载一个与@OneToMany 关系的字段我收到一个 LazyInitializationException
spring-boot 版本 2.3.4.RELEASE
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Conta> accounts = new ArrayList<>();
我的处理器
@Slf4j
public class AccountItemProcessor implements ItemProcessor<AccountMaster, List<AccountBatch>> {
@Autowired
private ContaBatchConfigProperties contaBatchConfigProperties;
@Override
public List<AccountBatch> process(AccountMaster accountMaster) throws Exception {
List<AccountBatch> accountBatchList = new ArrayList<>();
for (Accounts obj: accountMaster.getAccounts()) {
accountBatchList.add(ContaBatch.of(obj, contaBatchConfigProperties));
accountBatchList.add(ContaBatch.of(accountMaster, contaBatchConfigProperties, obj));
}
return accountBatchList;
}
}
错误:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.example.AccountMaster.accounts, could not initialize proxy - no Session
我将批处理数据源创建为主
@Bean(name="batchDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.batch.datasource")
public DataSource batchDataSource(){
return DataSourceBuilder.create().build();
}
解决方案
@OneToMany
当您在事务外部操作字段时会发生延迟初始化。
开启交易
对于开始交易,您将有不同的方法
- 在您的 Service 方法的公共方法上使用 @Transactional(您的案例的过程)
- 使用 TransactionTemplate 打开一个事务
多数据源和事务管理器
当您在 MonoDatasource 项目中时,这应该足够了,但在 MultiDatasource 中,您必须小心数据来自哪个数据源。为此,您将不得不使用相应的事务管理器。
为此,您可以transactionManager=myTransactionManagerForDatasourceA
在@Transactional
注释中添加属性。
如果您没有(或不知道名称)事务管理器,则必须定义它
定义一个主事务管理器
如果您不想在所有@Transactional
注释中使用 transactionManager 值,因为在 99% 的情况下您将使用相同的 Datasource,您可以使用 @Primary 注释您的 dataSource bean 方法。默认情况下,@Transactional 将使用主事务管理器,如果必须,您可以使用事务管理器注释值来使用其他事务管理器
推荐阅读
- python - 为什么我的布尔值在while循环中没有变化?
- mysql - 从规范化表中选择数据
- javascript - 用户在'beforeunload'之后取消加载
- python - 如何从我的 JSON 数据中提取和打印值列表?
- c# - 在 Xamarin 中播放声音
- java - 线程“main”中的异常 java.util.NoSuchElementException 错误并且程序打印出错误的结果
- c++ - 如何访问我正在从事的 glade/gtk 项目的代码
- javascript - 我无法让我的新机器人“imagesearch”工作,正在寻求帮助
- swiftui - 下划线 VStack 的内容
- image - FFMPEG 用于将视频转换为 MacOS 图像序列的多任务