Остановка Spring Jpa + Hibernate от перезаписи значений в объединенной базе данных - PullRequest
1 голос
/ 11 февраля 2020

Я начинаю изучать Hibernate и Spring JPA и пытаюсь соединить две таблицы, но не могу заставить его работать должным образом. Вот мои классы:


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

    @OneToMany( fetch = FetchType.EAGER, cascade = CascadeType.ALL)
            @JoinColumn(name="username", referencedColumnName="username")
    List<UserRole> userRoles;
    private String email;
    private String name;
    private String password;
    private String grp;
    @Id
    private String username;

    public User() {
        userRoles=new ArrayList<>();
        userRoles.add(new UserRole("default"));
    }
@Entity
@Table(name = "roles")
public class UserRole  {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

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

    @Override
    public String toString() {
        return  roleName;
    }

    public UserRole(String role) {
        roleName = role;
    }

Проблема, с которой я сталкиваюсь, заключается в том, что при использовании метода сохранения JpaRepository для обновления пользователя значения ролей повторяются в таблице ролей. Например, если у меня есть пользователь с ADMIN ROLE и я использую команду сохранения, чтобы сначала добавить пользователя в таблицу, а затем обновить его электронную почту, я получаю два идентичных поля роли с разными идентификаторами (если я добавляю обнуляемый тег false) В противном случае он просто получает мне новое поле с пустым именем пользователя, ролью ADMIN и новым идентификатором. Я понимаю, что это может быть связано с generationType.IDENTITY. Но если я делаю это АВТО, я получаю исключение Table 'project2testing.hibernate_sequence'. Не могли бы вы помочь мне понять, что я делаю неправильно. Спасибо!

1 Ответ

0 голосов
/ 11 февраля 2020

То, что вы, вероятно, хотите, это таблица внешних ссылок и ManyToMany, которых я здесь не вижу. Теперь вы говорите, что между пользователем и множеством ролей существует единая связь. Другими словами, роли нельзя использовать повторно. Они принадлежат пользователю, и каждый раз, когда вы назначаете пользователю роль, даже если роль с таким именем уже существует, создается новая роль.

Вместо этого ManyToMany имеет больше смысла. Роль традиционно не является уникальной вещью для пользователя, и многие пользователи могут иметь одну и ту же роль.

Один из способов достижения этого заключается в следующем:

@ManyToMany(targetEntity = UserRole.class, fetch = FetchType.EAGER)
@JoinColumn(name="user_role_xref", 
    joinColumns = @JoinColumn(name = "username", referencedColumnName = "username"),
    inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
Set<UserRole> userRoles;

Это создаст user_role_xref таблица, которая будет содержать два столбца: username и role_id, которые ссылаются на User.username и UserRole.id соответственно. Обратите внимание, что для этого потребуется управлять UserRole независимо от пользователей, что представляется более желательным в этом сценарии. То, что роль в данный момент не назначена пользователю, не означает, что ее следует удалить.

...