更新oneToMany实体会将parent设置为null

时间:2016-03-17 01:29:55

标签: java hibernate jpa one-to-many many-to-one

我在Role实体上列出了User个实体,并与@OneToMany关系相关联。当我更改User实体上的列表,即更改角色时,hibernate会删除旧角色并根据需要添加新角色。但是,Role实体上的外键字段设置为null。

您能否解释为什么foregign键字段为空,以及如何更改它以便在更新时获取它?

User.java

@SerializedName("userrole")
@Expose
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Role>   userRoles = new ArrayList<Role>();

Role.java

@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行动

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=?

更新

根据评论中的要求调用数据库的方法

@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> {

感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我使用EntityManager并使用Hibernate这样做,它似乎工作正常。你是从List<Role> userRoles

中取出旧角色吗?

用户:

@Entity
public class User {
    @Id private String email;

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Role> userRoles = new ArrayList<Role>();

作用:

@Entity
public class Role {
    @Id @GeneratedValue private Long id;

    @ManyToOne
    private User user;

将其作为:

运行
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]