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-请你解释一下你的例子:userdigby.tyson
有role7
和userreed.robert
也有role7
。是同一个角色吗代码>在这两种情况下?如果是这样,那么就像@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]