JpaRepository 不会插入多对多数据

JpaRepository won't insert many-to-many data

我有使用 JPA 工具生成的用户实体和角色实体。 User 和 Role 是多对多的关系。我使用以下代码插入管理员,但是,没有数据插入 user_role table。我还注意到角色 class 有 @JoinTable 但用户 class 没有。有区别吗?

private void addAdmin() {
    User admin = new User();
    admin.setDisplayName("admin");

    Role role1 = new Role();
    role1.setRole("ROLE_SUPER_ADMIN");
    Role role2 = new Role();
    role2.setRole("ROLE_END_USER");
    List<Role> roles = new ArrayList<Role>();
    roles.add(role1);
    roles.add(role2);
    admin.setRoles(roles);
    userRepository.save(admin);
}

以下是我的用户 class:

@Entity
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private int id;

  @Column(name="display_name")
  private String displayName;

  //bi-directional many-to-many association to Role
  @ManyToMany(mappedBy="users")
  private List<Role> roles;
}

以下是我的角色class:

@Entity
@NamedQuery(name="Role.findAll", query="SELECT r FROM Role r")
public class Role implements Serializable {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private int id;

  private String role;

  //bi-directional many-to-many association to User
  @ManyToMany
  @JoinTable(
    name="user_role"
    , joinColumns={
        @JoinColumn(name="role_id")
        }
    , inverseJoinColumns={
        @JoinColumn(name="user_id")
        }
    )
  private List<User> users;
}

roles实体中的User关联是关联的反面(由mappedBy指定)。也就是说维护关联是Roleclass的职责,所以要让关联变化持久化,还得修改owner端:

role1.getUsers().add(admin);
role2.getUsers().add(admin);

不管怎样,双向关联的两边总是更新是一个很好的约定,这样反面的状态也能反映出owner方的变化。这就是为什么通常的做法是创建更改关联双方的辅助方法:

@Entity
public class User {

  //bi-directional many-to-many association to Role
  @ManyToMany(mappedBy="users")
  private List<Role> roles;

  public void addRole(Role role) {
    if (!roles.contains(role)) {
      roles.add(role);
      role.addUser(this);
    }
  }
}

@Entity
public class Role {

  //bi-directional many-to-many association to User
  @ManyToMany
  @JoinTable(
    ...
    )
  private List<User> users;

  public void addUser(User user) {
    if (!users.contains(user)) {
      users.add(user);
      user.addRole(this);
    }
  }  
}
@Entity
public class User {
    @ManyToMany
    private List<Role> roles;
}

@Entity
public class Role {
    @ManyToMany
    private List<User> users;
}

public class Auth {
    User newUser = new User("username","password");
    userDao.save(newUser);

    Role newRole_1 = new Role("ADMIN");
    Role newRole_2 = new Role("USER");
    roleDao.save(newRole_1);
    roleDao.save(newRole_2);

    List<Role> roles = roleDao.findAll();
    User user = userDao.findOne(user_id);  // e.g. Long user_id = 1L;
    for (Role role : roles) {
        user.getRoles().add(role);
    }
    userDao.save(user);

}

如果您创建了新对象:

    User user = new User();
    Role role = new Role();
    List<Role> roles = new ArrayList<>(); 

这个对象是暂时的,Hibernate 不能使用它们。 Hibernate 与持久对象一起工作。因此,您必须使用方法 save();找一个();找到所有();和其他