简体   繁体   English

JPA:在三个实体之间使用多个多对多关系后,冗余的SQL插入

[英]JPA: redundant sql insertions after using multiple many-to-many relations between three entities

I have User, Role and Permission entities and use embedded db for development purpose. 我有用户,角色和权限实体,并将嵌入式数据库用于开发目的。 User and Role have many-to-many relation and, also, Role and Permission have many-to-many relation too: 1) User entity: 用户和角色具有多对多关系,并且角色和权限也具有多对多关系: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) Role entity: 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) Permisson entity: 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)

And offcause my test populator: 并因为我的测试填充器:

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);
}

I expected that one user record, one role record and one permission record are created and inserted into particulars repos. 我希望创建一个用户记录, 一个角色记录和一个权限记录,并将其插入到详细信息存储库中。 All seems to be clean (without any exception) but rest clien show me that I have two role records and three permission records, for role for example: 一切看起来都很干净(没有任何异常),但是clien告诉我,我有两个角色记录和三个权限记录,例如:

{
"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
}

} }

In log I see that it is all created but why in such way I do not know yet, please help. 在日志中,我看到所有内容都已创建,但是为什么我还不知道为什么,请提供帮助。 log is here: https://www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0 日志在这里: https : //www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0

You are saving user ,Role , permission separately . 您正在分别保存用户,角色,权限。 This will result multiple records . 这将导致多个记录。 Since you have given Cascade All saving User Object will save role objects and permission objects too. 由于您已给出Cascade,因此所有保存的用户对象也将保存角色对象和权限对象。

try like this 这样尝试

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);

} }

See about cascade here . 在这里看到有关层叠的信息 Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM