Я хотел бы знать, почему spring jpa не удаляет строки, вызывающие ошибку ограничения, или способ сделать возможным редактирование объекта моей учетной записи с новыми ролями.

Следующие объекты участвуют в действии, которое я пытаюсь выполнить.

@Entity
@Table(name = "account")
class AccountEntity(uuid: UUID? = null,
                    @Column(nullable = false) val email: String,
                    @Column(nullable = false) val password: String,
                    @OneToMany(
                            mappedBy = "accountUuid",
                            cascade = [CascadeType.ALL],
                            fetch = FetchType.LAZY
                    ) val accountRolesEntity: List<AccountRolesEntity>) : BaseEntity(uuid)

@Entity
@Table(name = "account_roles")
class AccountRolesEntity(uuid: UUID? = null,
                         @Column(nullable = false) val accountUuid: UUID,
                         @OneToOne val role: RoleEntity) : BaseEntity(uuid)

@Entity
@Table(name = "role")
class RoleEntity(uuid: UUID? = null,
                 @Column(nullable = false) val name: String ) : BaseEntity(uuid)

Итак, я пытаюсь обновить роли определенной учетной записи.

Например: Если у X есть роли «просмотрщик» и «редактор», и предположим, что я хочу изменить его только на просмотрщик.

Я делаю следующие шаги:

  1. Запрос объекта учетной записи из базы данных
  2. установить новый accountRolesEntity (полученный от контроллера) для учетной записи
  3. Вызвать метод сохранения репозитория jpa

Метод в классе обслуживания:

fun updateExistingAccount(account: AccountDTO, adjustedRoles: List<RoleDTO>): AccountDTO {
    val mappedRoles: List<AccountRolesEntity> = adjustedRoles.map { accountRolesMapper.map(account.uuid, it) }
    val accountEntity = accountMapper.map(account, mappedRoles)
    return accountMapper.map(accountRepository.save(accountEntity))
}

Я получаю ошибку: org.postgresql.util.PSQLException: ОШИБКА: повторяющееся значение ключа нарушает уникальное ограничение "account_roles_account_uuid_role_uuid_key"

Это связано с тем, что в моей базе данных есть ограничение, гарантирующее, что учетная запись не может не иметь повторяющиеся роли. Оператор создания таблицы выглядит следующим образом:

CREATE TABLE account_roles (
                               uuid         UUID PRIMARY KEY,
                               account_uuid UUID NOT NULL REFERENCES account(uuid),
                               role_uuid    UUID NOT NULL REFERENCES role(uuid),
                               UNIQUE (account_uuid, role_uuid)
);

Для этого есть исправление, выполняя все действия 1 на 1: сначала удалить, а затем сделать новые вставки. Но для этого должен быть лучший способ.

0
J. Adam 13 Апр 2020 в 13:49
Похоже, ваша вставка не происходит в транзакции.
 – 
vsfDawg
13 Апр 2020 в 14:08
Мои знания ограничены, это слишком сложно для понимания
 – 
J. Adam
13 Апр 2020 в 14:16

1 ответ

На самом деле «AccountRolesEntity» не является сущностью, это таблица, которая поддерживает отношения двух сущностей, сохраняя id этих сущностей в таблице.

Поэтому для первого шага у вас должно получиться что-то вроде этого,

    @JoinTable(name = "account_role",
            joinColumns = @JoinColumn(name = "account")
            , inverseJoinColumns = @JoinColumn(name = "role"))
    @OneToMany(mappedBy = "accountUuid",
              cascade = [CascadeType.ALL],
              fetch = FetchType.LAZY) 
    val accountRolesEntity: List<AccountRolesEntity>) :BaseEntity(uuid)

И я думаю, что ваша проблема зависит от ваших каскадов и вашей диаграммы классов, поэтому проверьте их еще раз.

0
Amir Pezeshk 13 Апр 2020 в 14:31