Java 更新oneToMany实体会将父实体设置为空

Java 更新oneToMany实体会将父实体设置为空,java,hibernate,jpa,one-to-many,many-to-one,Java,Hibernate,Jpa,One To Many,Many To One,我有一个与@OneToMany关系链接的用户实体上的角色实体列表。当我更改用户实体上的列表,即更改角色时,hibernate会根据需要删除旧角色并添加新角色。但是,角色实体上的外键字段设置为空 你能解释一下为什么foregign键字段是空的吗?我该如何更改它以便在更新时提取它 User.java @SerializedName("userrole") @Expose @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade =

我有一个与
@OneToMany
关系链接的
用户
实体上的
角色
实体列表。当我更改
用户
实体上的列表,即更改角色时,hibernate会根据需要删除旧角色并添加新角色。但是,
角色
实体上的外键字段设置为空

你能解释一下为什么foregign键字段是空的吗?我该如何更改它以便在更新时提取它

User.java

@SerializedName("userrole")
@Expose
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Role>   userRoles = new ArrayList<Role>();
@ManyToOne
@JoinColumn(name = "user")
private User user;
之前的表格

+----+------+------------------------+
| id | role | user                   |
+----+------+------------------------+
|  1 |    0 | digby.tyson@gmail.com  |
|  2 |    1 | digby.tyson@gmail.com  |
|  3 |    2 | digby.tyson@gmail.com  |
|  4 |    3 | digby.tyson@gmail.com  |
|  5 |    4 | digby.tyson@gmail.com  |
|  6 |    5 | digby.tyson@gmail.com  |
|  7 |    6 | digby.tyson@gmail.com  |
|  8 |    7 | digby.tyson@gmail.com  |
|  9 |    5 | ronny.polley@gmail.com |
| 10 |    6 | ronny.polley@gmail.com |
| 11 |    7 | reed.robert@gmail.com  |
+----+------+------------------------+
之后的表格

+----+------+------------------------+
| id | role | user                   |
+----+------+------------------------+
|  9 |    5 | ronny.polley@gmail.com |
| 10 |    6 | ronny.polley@gmail.com |
| 11 |    7 | reed.robert@gmail.com  |
| 12 |    0 | NULL                   |
| 13 |    1 | NULL                   |
| 14 |    2 | NULL                   |
| 15 |    5 | NULL                   |
| 16 |    6 | NULL                   |
| 17 |    7 | NULL                   |
+----+------+------------------------+
休眠操作

Hibernate: select userroles0_.user as user3_2_0_, userroles0_.id as id1_1_0_, userroles0_.id as id1_1_1_, userroles0_.role as role2_1_1_, userroles0_.user as user3_1_1_ from role userroles0_ where userroles0_.user=?
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: insert into role (role, user) values (?, ?)
Hibernate: update user set first_name=?, last_name=?, middle_name=?, organisation_id=? where email=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
Hibernate: delete from role where id=?
更新

+----+------+------------------------+
| id | role | user                   |
+----+------+------------------------+
|  1 |    0 | digby.tyson@gmail.com  |
|  2 |    1 | digby.tyson@gmail.com  |
|  3 |    2 | digby.tyson@gmail.com  |
|  4 |    3 | digby.tyson@gmail.com  |
|  5 |    4 | digby.tyson@gmail.com  |
|  6 |    5 | digby.tyson@gmail.com  |
|  7 |    6 | digby.tyson@gmail.com  |
|  8 |    7 | digby.tyson@gmail.com  |
|  9 |    5 | ronny.polley@gmail.com |
| 10 |    6 | ronny.polley@gmail.com |
| 11 |    7 | reed.robert@gmail.com  |
+----+------+------------------------+
根据注释中的请求调用数据库的方法

@Override
@Transactional
public User update(User user) throws UserNotFoundException {
    String updatedUserEmail = user.getEmail();

    if (userRepository.findByEmail(updatedUserEmail) == null)
        throw new UserNotFoundException();

    return userRepository.save(user);

}

@Transactional
public interface UserRepository extends CrudRepository<User, Long> {
@覆盖
@交易的
公共用户更新(用户用户)引发UserNotFoundException{
字符串updateUserEmail=user.getEmail();
if(userRepository.findByEmail(updateUserEmail)==null)
抛出新的UserNotFoundException();
返回userRepository.save(用户);
}
@交易的
公共接口UserRepository扩展了Crudepository{

感谢您提前提供的帮助。

映射是正确的,现在您要实现的是,当从用户中删除角色时,您希望删除该角色(orphanRemoving=true)

这是一种双向关联,因此您需要做的是在两侧进行更改,以保持对象模型的一致性:

// remove role from user one-to-many
user.getUserRoles().remove(roleToBeDeleted);
// remove the many-to-one association
roleToBeDeleted.setUser(null);

我使用EntityManager和Hibernate完成了这项工作,它似乎工作正常。您是否将旧角色从
用户角色列表中删除

用户:

将其运行为:

User u = em.find(User.class, "test@test.com");
Role e = new Role();
e.setUser(u);
u.getUserRoles().remove(0);
u.getUserRoles().add(e);
em.merge(u);
给我:

Hibernate: insert into Role (user_email, id) values (?, ?)
Hibernate: delete from Role where id=?
Hibernate: select * from role
角色表中只有一行:

[2, test@test.com]

从表数据看,这是一个多人关系。但在您的实体中,您映射的是一个多人关系。您还需要将您的实体更新为多人关系。同时发布执行更新的代码。我认为角色应该是具有独立于用户生命周期的实体。您将它们映射为
cascade=CascadeType.ALL,orphanRemoving=true
ie.当用户被删除时,它也会删除角色(不仅仅是用户和角色之间的关系)。这真的是你的意图吗?@AdamMichalik是的,我想删除一个用户,并从角色表中删除与该用户相关的所有角色。@SJC-请你解释一下你的例子:user
digby.tyson
有role
7
和user
reed.robert
也有role
7
。是同一个角色吗在这两种情况下?如果是这样,那么就像@Madhusudana Reddy Sunnapu所说的那样-这是一种多对多的关系,因为许多用户可以拥有相同的角色,而一个用户可以拥有多个角色。现在,当你删除用户
digby.tyson
时,你真的希望该角色
7
被删除,从而从用户
reed.robert
中删除吗?还是您只想删除将角色
7
分配给
digby.tyson
的任务吗?删除
用户时,只需删除
digby.tyson
中的角色。所有其他角色都保留在表中。正如@madhusudanareddysunapu建议的那样,我在用户上添加了
@manytomy
,我在l上得到了一个错误aunch
非法尝试将非集合映射为@OneToMany、@ManyToMany或@collectionfelments
感谢btwThanks的回复,但是前后表是当前发生的情况。我的问题是我不希望after表中的
NULL
值,我希望将它们完全删除。上面的操作会这样做吗,或者我说你的答案是做饭后准备,对吗?先试试上面的方法……让我知道;)……应该很好用!
[2, test@test.com]