我有实体 User
和School
。
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);
一切都很好,数据正在保存到 school
和user
表。
但是
我需要添加not null constraint
至user.school_id
列(我使用 liquibase
),当我这样做并尝试保存 School
时再次实体,我收到:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'school_id' cannot be null
.
怎么会呢?又该如何解决呢?
最佳答案
这是双向 JPA 关系的问题。 更新关系的一个方向(在您的情况下 School.users
)不会自动更新关系的相反方向(在您的情况下用户.学校
)。 您需要明确地执行此操作。
为了保存它们,您需要循环遍历用户列表并将学校字段设置为您想要的学校。之后初始化学校中的用户列表并保存。像这样的事情:
users.stream().forEach(user -> user.setSchool(school));
school.setUsers(users);
schoolRepository.save(school);
顺便说一句,我建议用 google 搜索一下双向 JPA 关系的含义。经过一番研究后,您很可能会得出尽可能避免这种情况的结论。就我个人而言,在我的职业生涯中只需要使用少量的双向 JPA 关系。在绝大多数情况下,单向关系足以满足您的需求。
关于java - 由于非空约束,实体保存失败。 Spring 启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50365173/