LazyInitializationException при доступе к коллекции LAZY на пользователя - PullRequest
0 голосов
/ 16 июня 2019

У меня есть класс 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 Ответ

1 голос
/ 17 июня 2019

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;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...