JPA:在三个实体之间使用多个多对多关系后冗余 sql 插入
JPA: redundant sql insertions after using multiple many-to-many relations between three entities
我有用户、角色和权限实体,并使用嵌入式数据库进行开发。 User 和 Role 具有多对多关系,而且 Role 和 Permission 也具有多对多关系:
1)用户实体:
@Entity
@Table(name = "usr")
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Serializable {
private static final long serialVersionUID = 818129969599480161L;
/**
* Unique id for the User. "@Id" declare the parameter as the primary key
* "@GeneratedValue" indicates JPA 2 (and behind Hibernate) which strategy
* to use for creating a new value.
* "GenerationType.AUTO" value allow JPA implementation to use the better way depending to the RDBMS used.
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
/**
* Login of the user. No annotation here, the parameter will be automatically mapped in the table.
*/
private String login;
/**
* Password of the user. No annotation here, the parameter will be automatically mapped in the table.
*/
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "USER_ROLES",
joinColumns =
@JoinColumn(name = "user_id"),
inverseJoinColumns =
@JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
.....(getters and setters)
2)角色实体:
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String roleName;
@ManyToMany(mappedBy = "roles", fetch=FetchType.EAGER)
private Set<User> users = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "ROLE_PERMISSION",
joinColumns =
@JoinColumn(name = "ROLE_ID"),
inverseJoinColumns =
@JoinColumn(name = "PERMISSION_ID"))
private Set<Permission> permissions = new HashSet<>();
.....(getters and setters)
3) 权限实体:
@Entity
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String permissionName;
@ManyToMany(mappedBy = "permissions", fetch=FetchType.EAGER, cascade = {})
private Set<Role> roles = new HashSet<>();
.....(getters and setters)
并且因为我的测试填充器:
public void afterPropertiesSet() throws Exception {
_logger.debug("setting test uses data");
Permission permission = new Permission();
permission.setPermissionName("PERM_SAVE_PRODUCT");
permissionRepository.save(permission);
Role role = new Role();
role.setRoleName("ROLE_ADMIN");
Set<Permission> permissions = new HashSet<>();
permissions.add(permission);
role.setPermissions(permissions);
roleRepository.save(role);
User user = new User();
user.setLogin("dmitro");
user.setPassword("2424");
user.setStatus(UserStatus.ACTIVE);
Set<Role> roles = new HashSet<Role>();
roles.add(role);
user.setRoles(roles);
userRepository.save(user);
}
我预计一个用户记录,一个角色记录和一个权限记录是创建并插入到详细信息回购中。
一切似乎都很干净(无一例外),但其他客户端显示我有 two 角色记录和 three 权限记录,例如角色:
{
"links": [
],
"content": [
{
"links": [
{
"rel": "roles.Role.permissions",
"href": "http://localhost:8080/admin/roles/1/permissions"
},
{
"rel": "self",
"href": "http://localhost:8080/admin/roles/1"
},
{
"rel": "roles.Role.users",
"href": "http://localhost:8080/admin/roles/1/users"
}
],
"roleName": "ROLE_ADMIN"
},
{
"links": [
{
"rel": "roles.Role.permissions",
"href": "http://localhost:8080/admin/roles/2/permissions"
},
{
"rel": "self",
"href": "http://localhost:8080/admin/roles/2"
},
{
"rel": "roles.Role.users",
"href": "http://localhost:8080/admin/roles/2/users"
}
],
"roleName": "ROLE_ADMIN"
}
],
"page": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 1
}
}
在日志中我看到它已经全部创建了但是为什么这样我还不知道,请帮助。 log 在这里:https://www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0
您正在分别保存用户、角色、权限。这将产生多个记录。由于您已给出 Cascade All 保存用户对象也将保存角色对象和权限对象。
这样试试
public void afterPropertiesSet() throws Exception {
_logger.debug("setting test uses data");
User user = new User();
user.setLogin("dmitro");
user.setPassword("2424");
user.setStatus(UserStatus.ACTIVE);
Set<Role> roles = new HashSet<Role>();
Role role = new Role();
role.setRoleName("ROLE_ADMIN");
Set<Permission> permissions = new HashSet<>();
Permission permission = new Permission();
permission.setPermissionName("PERM_SAVE_PRODUCT");
permissions.add(permission);
role.setPermissions(permissions);
roles.add(role);
user.setRoles(roles);
userRepository.save(user);
}
查看级联here。希望对你有帮助
我有用户、角色和权限实体,并使用嵌入式数据库进行开发。 User 和 Role 具有多对多关系,而且 Role 和 Permission 也具有多对多关系: 1)用户实体:
@Entity
@Table(name = "usr")
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Serializable {
private static final long serialVersionUID = 818129969599480161L;
/**
* Unique id for the User. "@Id" declare the parameter as the primary key
* "@GeneratedValue" indicates JPA 2 (and behind Hibernate) which strategy
* to use for creating a new value.
* "GenerationType.AUTO" value allow JPA implementation to use the better way depending to the RDBMS used.
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
/**
* Login of the user. No annotation here, the parameter will be automatically mapped in the table.
*/
private String login;
/**
* Password of the user. No annotation here, the parameter will be automatically mapped in the table.
*/
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "USER_ROLES",
joinColumns =
@JoinColumn(name = "user_id"),
inverseJoinColumns =
@JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
.....(getters and setters)
2)角色实体:
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String roleName;
@ManyToMany(mappedBy = "roles", fetch=FetchType.EAGER)
private Set<User> users = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "ROLE_PERMISSION",
joinColumns =
@JoinColumn(name = "ROLE_ID"),
inverseJoinColumns =
@JoinColumn(name = "PERMISSION_ID"))
private Set<Permission> permissions = new HashSet<>();
.....(getters and setters)
3) 权限实体:
@Entity
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String permissionName;
@ManyToMany(mappedBy = "permissions", fetch=FetchType.EAGER, cascade = {})
private Set<Role> roles = new HashSet<>();
.....(getters and setters)
并且因为我的测试填充器:
public void afterPropertiesSet() throws Exception {
_logger.debug("setting test uses data");
Permission permission = new Permission();
permission.setPermissionName("PERM_SAVE_PRODUCT");
permissionRepository.save(permission);
Role role = new Role();
role.setRoleName("ROLE_ADMIN");
Set<Permission> permissions = new HashSet<>();
permissions.add(permission);
role.setPermissions(permissions);
roleRepository.save(role);
User user = new User();
user.setLogin("dmitro");
user.setPassword("2424");
user.setStatus(UserStatus.ACTIVE);
Set<Role> roles = new HashSet<Role>();
roles.add(role);
user.setRoles(roles);
userRepository.save(user);
}
我预计一个用户记录,一个角色记录和一个权限记录是创建并插入到详细信息回购中。 一切似乎都很干净(无一例外),但其他客户端显示我有 two 角色记录和 three 权限记录,例如角色:
{
"links": [
],
"content": [
{
"links": [
{
"rel": "roles.Role.permissions",
"href": "http://localhost:8080/admin/roles/1/permissions"
},
{
"rel": "self",
"href": "http://localhost:8080/admin/roles/1"
},
{
"rel": "roles.Role.users",
"href": "http://localhost:8080/admin/roles/1/users"
}
],
"roleName": "ROLE_ADMIN"
},
{
"links": [
{
"rel": "roles.Role.permissions",
"href": "http://localhost:8080/admin/roles/2/permissions"
},
{
"rel": "self",
"href": "http://localhost:8080/admin/roles/2"
},
{
"rel": "roles.Role.users",
"href": "http://localhost:8080/admin/roles/2/users"
}
],
"roleName": "ROLE_ADMIN"
}
],
"page": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 1
}
}
在日志中我看到它已经全部创建了但是为什么这样我还不知道,请帮助。 log 在这里:https://www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0
您正在分别保存用户、角色、权限。这将产生多个记录。由于您已给出 Cascade All 保存用户对象也将保存角色对象和权限对象。
这样试试
public void afterPropertiesSet() throws Exception {
_logger.debug("setting test uses data");
User user = new User();
user.setLogin("dmitro");
user.setPassword("2424");
user.setStatus(UserStatus.ACTIVE);
Set<Role> roles = new HashSet<Role>();
Role role = new Role();
role.setRoleName("ROLE_ADMIN");
Set<Permission> permissions = new HashSet<>();
Permission permission = new Permission();
permission.setPermissionName("PERM_SAVE_PRODUCT");
permissions.add(permission);
role.setPermissions(permissions);
roles.add(role);
user.setRoles(roles);
userRepository.save(user);
}
查看级联here。希望对你有帮助