在用户上访问LAZY集合时出现LazyInitializationException

时间:2019-06-16 20:59:08

标签: java spring hibernate spring-boot jpa

我有一个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。这里有什么解决方法?

1 个答案:

答案 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;
}