我有一个User类,其中包含一组延迟加载的对象。
class User {
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@Getter
@Column(nullable = false)
private List<Wallet> wallets= new ArrayList<>();
}
现在我还有一个Transaction类,其中包含对用户钱包的引用。
class Transaction {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "senderWallet", referencedColumnName = "id")
private Wallet senderWallet;
}
现在,我创建了一个服务,该服务应该为给定用户获取交易:
@Transactional
public List<Transaction> getTransactionsForUser(User user) {
List<Wallet> wallets = user.getWallets();
List<Transaction> transactions = new ArrayList<>();
for (Wallet wallet : wallets) {
transactions.addAll(transactionRepository.findBySenderWallet(wallet));
}
return transactions;
}
在控制器中,我这样获取当前登录的用户:
User user = ((UserPrincipal) authentication.getPrincipal()).getUser();
然后,我致电服务:
List<Transaction> transactions = transactionService.getTransactionsForUser(user);
这将引发LazyInitializationException。这里有什么解决方法?
答案 0 :(得分:1)
1),我认为您的@OneToMany
应该定义为mappedBy
:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
@Getter
@Column(nullable = false)
private List<Wallet> wallets= new ArrayList<>();
2)您正在传递一个实体User
,该实体是在另一个似乎已关闭的交易环境中获取的。
在服务方法中,您应该在进行操作之前对该实体执行合并。 Srping Data Jpa save
方法已实现合并,因此调用就足够了:
@Transactional
public List<Transaction> getTransactionsForUser(User user) {
userRepository.save(user); // Add this <---
List<Wallet> wallets = user.getWallets();
List<Transaction> transactions = new ArrayList<>();
for (Wallet wallet : wallets) {
transactions.addAll(transactionRepository.findBySenderWallet(wallet));
}
return transactions;
}