【问题标题】:JPA: redundant sql insertions after using multiple many-to-many relations between three entitiesJPA:在三个实体之间使用多个多对多关系后的冗余 sql 插入
【发布时间】:2015-01-30 01:46:03
【问题描述】:

我有用户、角色和权限实体,并使用嵌入式数据库进行开发。 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);
}

我希望创建 一个 用户记录、一个 角色记录和 一个 权限记录并插入到详细信息库中。 一切似乎都很干净(无一例外),但其余客户告诉我我有 两个 角色记录和 三个 权限记录,例如角色:

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

}

在日志中我看到它都是创建的,但是为什么我还不知道为什么会这样,请帮忙。 日志在这里:https://www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0

【问题讨论】:

    标签: java entity-framework hibernate jpa spring-data


    【解决方案1】:

    您正在分别保存用户、角色、权限。这将导致多条记录。由于您已提供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 。希望对你有帮助

    【讨论】:

    • 非常感谢!您提供的文档和代码sn-p解决了我的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2019-04-07
    相关资源
    最近更新 更多