CommandLineRunner,执行失败,Spring Boot

时间:2019-10-27 20:01:29

标签: java spring hibernate

无法将硬编码数据添加到数据库。 如果我评论有关银行的所有信息,而只是使用空银行列表保存(帐户),则它将数据保存到db。

@带有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:无法执行CommandLineRunner -由以下原因引起:org.springframework.dao.InvalidDataAccessApiUsageException:传递给持久对象的分离实体: -由以下原因引起:org.hibernate.PersistentObjectException:传递给持久对象的分离实体:

1 个答案:

答案 0 :(得分: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,以确保您的实体处于持久状态