Я пытаюсь установить данные в базу данных с помощью интерфейса CommandLineRunner.

Если я удалю все об экземпляре bank и сохраню account с нулевым списком банков, он сохранит данные в базе данных.

Класс компонента с CommandLineRunner:

@Override
    public void run(String... args) throws Exception {
        List<Bank> banks = new ArrayList<>();
        Bank bank = new Bank("Приват Банк", 5000.0f);
        Bank bank2 = new Bank("UkrsibBank", 3000.1f);
        banks.add(bank);
        banks.add(bank2);
        bankAccountRepository.save(bank);
        bankAccountRepository.save(bank2);
        Account account = new Account(15000.2f, 1200.5f,  banks);
        accountRepository.save(account);
    }

Мои объекты:

@Entity
@Data
@NoArgsConstructor
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "total_balance")
    private float totalBalance;

    private float cash;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "account_banks", joinColumns = @JoinColumn(name = "account_id"),
            inverseJoinColumns = @JoinColumn(name = "bank_id") )
    private List<Bank> banks;

    public Account(float totalBalance, float cash, List<Bank> banks) {
        this.totalBalance = totalBalance;
        this.cash = cash;
        this.banks = banks;
    }
}
@Entity
@Data
@NoArgsConstructor
public class Bank implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
    @Column(name = "account_balance")
    private float balance;

    public Bank(String name, float balance) {
        this.name = name;
        this.balance = balance;
    }
}

В чем моя ошибка? Трассировки стека:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: 
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist:
0
andrew17 27 Окт 2019 в 23:01

1 ответ

Лучший ответ

Вы устанавливаете каскадный тип для этого отношения как cascade = CascadeType.ALL Когда вы вызываете accountRepository.save(account), Hibernate пытается сохранить связанные с ним объекты (банки), но до этого вы еще вручную сохранили их (после этого они находятся в отсоединенном состоянии). Это вызывает ошибку. Думаю, для этого есть три возможных решения:

  • Полностью удалите каскадную стратегию, если вы хотите, чтобы ваши сущности сохранялись независимо.
  • Сохраняйте объекты Bank транзитивно с помощью Account
Bank bank = new Bank("Приват Банк", 5000.0f);
        Bank bank2 = new Bank("UkrsibBank", 3000.1f);
        banks.add(bank);
        banks.add(bank2);
        Account account = new Account(15000.2f, 1200.5f,  banks);
        accountRepository.save(account);
  • Украсьте метод run аннотацией @Transactional, чтобы гарантировать, что ваши объекты будут в постоянном состоянии
1
Anthony 10 Апр 2020 в 19:40