实体保存失败,非空约束。春季启动

时间:2018-05-16 07:50:22

标签: java spring spring-boot jpa spring-data-jpa

我有实体UserSchool。 在MySQL数据库中有一个外键(一个学校有很多用户)。

User我有:

@ManyToOne(optional = false, targetEntity = School.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "schoolId", referencedColumnName = "id", nullable = false)
private School school;

School我有:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = User.class)
@JoinColumn(name = "schoolId")
private List<User> users;

如果我要将School实体保存在其中List<User>,请致电

schoolRepository.save(school);

一切正常,数据被保存到schooluser表。

BUT

我需要将not null constraint添加到user.school_id列(我使用liquibase),当我这样做并尝试再次保存School实体时,我会收到:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'school_id' cannot be null

为什么?它怎么能修复?

1 个答案:

答案 0 :(得分:2)

这是双向JPA关系的问题。 更新一个关系方向(在您的情况下为School.users不会自动更新相反的关系方向(在您的情况下为User.school)。 您需要明确地执行此操作。

为了保存它们,您需要循环浏览用户列表并将学校字段设置为所需的学校。之后,初始化学校用户列表并保存。像这样:

users.stream().forEach(user -> user.setSchool(school));
school.setUsers(users);
schoolRepository.save(school);   
顺便说一下,我建议谷歌围绕双向JPA关系的影响。经过一些研究,你很可能最终得出结论,以尽可能避免它。在我的职业生涯中,个人只需要使用少数双向JPA关系。在绝大多数情况下,单向关系足以满足您的需求。