Hibernate добавляет ненужную строку в таблицу ролей после регистрации пользователя - PullRequest
1 голос
/ 27 апреля 2019

Я пытаюсь добавить функциональность в мое веб-приложение с регистрацией пользователя.Webapp основан на весенней загрузке, hibernate и базе данных mysql, внешний интерфейс - угловой.Как правило, процедура создания пользователя работает правильно, пользовательские данные правильно отправляются из внешнего интерфейса в бэкэнд через json и сохраняются в базе данных в таблице shop_user (со всеми пользовательскими данными, такими как имя, фамилия, адрес и т. Д.), Но они НЕ ДАЮТ'T имею столбец роли.

У меня также есть таблица' роль ', которая должна быть:

id     name
1      USER
2      ADMIN

и объединенная таблица user_role, которая состоит из user_id из таблицы shop_user и идентификатора роли из таблицыроль, поэтому она должна выглядеть следующим образом:

id_user    id_role
1          2
2          1
3          1

Когда пользователь создается на веб-сайте, жестко задана роль по умолчанию для пользователя USER.Кажется, это работает довольно хорошо, поскольку он добавляет новую строку в shop_user и добавляет строку в user_role, но ... он также создает новую строку в таблице 'role'.

итак, в конце 'Таблица role 'выглядит следующим образом:

id     name
1      ADMIN
2      USER
3      USER
4      USER
5      USER
99     USER

`

, хотя это не блокирующая ошибка, которая мешает работе приложения, к сожалению, это не« как должно работать »... кактаблица должна состоять только из двух строк ролей (и, возможно, дополнительных, в будущем), но не должна умножаться для каждого пользователя!

вот некорректный код пользователя:

Пользователь

@Entity
@Table(name = "shop_user")
public class User extends AbstractEntity {

@Column
private String firstName;

@Column
private String lastName;

@Column
private String addressLine;

@Column
private String city;

@Column
private String country;

@Column
private String zipCode;

@Column
private String phoneNumber;

@Column
private String email;

@Column
private String password;

@ManyToMany(cascade = CascadeType.ALL,  fetch = FetchType.EAGER)
@JoinTable(name = "user_role",
        joinColumns = @JoinColumn(name = "id_user", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "id_role", referencedColumnName = "id"),
        uniqueConstraints = {@UniqueConstraint(columnNames = {"id_user", "id_role"})})
private List<Role> roles;

public User() {
}

public User(User user) {
    setId(user.getId());
    this.firstName = user.getFirstName();
    this.lastName = user.getLastName();
    this.addressLine = user.getAddressLine();
    this.city = user.getCity();
    this.country = user.getCountry();
    this.zipCode = user.getZipCode();
    this.phoneNumber = user.getPhoneNumber();
    this.email = user.getEmail();
    this.password = user.getPassword();
    this.roles= user.getRoles();
}

public List<Role> getRoles() {
    return roles;
}

public void setRoles(List<Role> roles) {
    this.roles = roles;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getAddressLine() {
    return addressLine;
}

public void setAddressLine(String addressLine) {
    this.addressLine = addressLine;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public String getCountry() {
    return country;
}

public void setCountry(String country) {
    this.country = country;
}

public String getZipCode() {
    return zipCode;
}

public void setZipCode(String zipCode) {
    this.zipCode = zipCode;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}
}

Реализация роли:

Роль

@Entity
@Table(name = "role")
public class Role extends AbstractEntity {

    @Column
    private String name;

    @ManyToMany(mappedBy = "roles", cascade = CascadeType.PERSIST)
    private List<User> users;

    public Role(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

Абстрактная сущность:

AbstractEntity

@MappedSuperclass
public abstract class AbstractEntity implements Persistable<Long> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public Long getId() {
        return id;
    }

    @Override
    public boolean isNew() {
        return id == null;
    }
}

Служба пользователя:

UserServiceImpl

@Service
public class UserServiceImpl extends AbstractServiceImpl<User, UserDTO> implements UserService {

    private final UserRepository userRepository;
    private final UserConverter userConverter;

    public UserServiceImpl(UserRepository userRepository, UserConverter 
userConverter) {
        this.userRepository = userRepository;
        this.userConverter = userConverter;
    }

    @Override
    protected JpaRepository<User, Long> getRepository() {
        return userRepository;
    }

    @Override
    protected Converter<User, UserDTO> getConverter() {
        return userConverter;
    }

    @Override
    @Transactional
    public User registerUser(User user) {
        List<Role> roles = new LinkedList<>();
        roles.add(new Role("USER"));
        user.setRoles(roles);
        return userRepository.save(user);
    }}

Я почти уверен, что это касается отображения отношений в Hibernate и создания объектов, но не могу понять это ...

Любая помощьБуду признателен, спасибо!

1 Ответ

1 голос
/ 27 апреля 2019

Проблема здесь:

@Override
@Transactional
public User registerUser(User user) {
    List<Role> roles = new LinkedList<>();
    roles.add(new Role("USER"));
    user.setRoles(roles);
    return userRepository.save(user);
}}

Поскольку отношение Пользователь -> Роль является каскадным сохранением, (новая) роль new Role("USER") также сохраняется, и вы получили новую Роль для каждого пользователя вместо повторного использования существующей.

Решение заключается в проверке существования роли с именем = USER. Если не существует, вставьте его. В противном случае добавьте существующий в коллекцию roles.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...