Моделирование вложенных объектов

#hibernate #spring-data-jpa

#переход в спящий режим #spring-данные-jpa

Вопрос:

Будучи новичком в hibernate / jpa, я сталкиваюсь с трудностями в том, как правильно моделировать вложенные объекты, мое требование, пользователь -> иметь много ролей -> у каждой роли есть много разрешений

Каждое разрешение для роли должно сохраняться в виде отдельной строки в таблице. И, необходимо иметь отдельные таблицы для пользователей и их ролей; опять же, каждая роль пользователя должна сохраняться в виде отдельной строки в таблице. Я написал ниже; но это не позволяет мне создавать новых пользователей с уже определенными ролями…

 @Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID",strategy = "org.hibernate.id.UUIDGenerator")
    public UUID id;

    @Column(name = "username")
    public String name;

    @Column(name = "password")
    public String password;

    @OneToMany(cascade = CascadeType.ALL, mappedBy="user")
    @LazyCollection(LazyCollectionOption.FALSE)
    public List<UserRole> roles;
}

@Entity
@Table(name = "user_roles")
public class UserRole implements Serializable {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID",strategy = "org.hibernate.id.UUIDGenerator" )
    public UUID id;

    @ManyToOne
    @JoinColumn(name="username", nullable=false, referencedColumnName = "username")
    public User user;

    @Column(name = "role_name")
    public String roleName;

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    @JoinColumn(name = "role_name", referencedColumnName = "role_name")
    public List<RolePermission> permissions;

}

@Entity
@Table(name = "roles_permissions")
public class RolePermission implements Serializable {

    @Id
    @Column(name = "role_name")
    public String roleName;

    @Id
    @Column(name = "permission")
    public String permission;
}
  

Получаем приведенную ниже ошибку,

2019-03-06 21:25:22.643 ОШИБКА 48896 — [nio-8090-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : ОШИБКА: дублирующее значение ключа нарушает уникальное ограничение «uk_40fvvy071dnqy9tywk6ei7f5r» Подробно: Ключ (role_name)= (владелец) уже существует.

Ответ №1:

Заработало после правильного моделирования UserRole, ниже приведен мой новый класс entity для UserRole,

 @Entity
@Table(name = "user_roles")
public class UserRole implements Serializable {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(
            name = "UUID",
            strategy = "org.hibernate.id.UUIDGenerator"
    )
    public UUID id;

    @ManyToOne
    @JoinColumn(name="username", nullable=false, referencedColumnName = "username")
    public User user;

    @Column(name = "role_name")
    public String roleName;

    @ManyToMany
    @JoinTable(name = "roles_permissions",joinColumns = @JoinColumn(name = "role_name"))
    public List<RolePermission> permissions;

}