2015-01-30 1 views
0

У меня есть объекты User, Role и Permission и используются встроенные db для целей разработки. Пользователь и роль имеют много-ко-многим, а также, роль и разрешение иметь много-ко-многим тоже: объекта 1) Пользователь:JPA: избыточные sql-вставки после использования множественных отношений «много-ко-многим» между тремя объектами

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

И offcause мой тест 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); 
} 

Я ожидал, что один запись пользователя, одна роль записи и один разрешение записи создаются и вставляются в частностях операции РЕПО. Все, кажется, быть чистыми (без исключения), но отдыхать 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 
} 

}

В журнале Я вижу, что все это создано, но почему таким образом я еще не знаю, пожалуйста, помогите. log is here: https://www.dropbox.com/s/orx3c9p023bxmti/log.txt?dl=0

ответ

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. Надеюсь, это поможет

+0

Большое вам спасибо! Документация и фрагмент кода, предоставленные вами, разрешены моим вопросом – Dimon

Смежные вопросы