首页 > 解决方案 > Jpa 映射表未在约束错误时删除

问题描述

我想知道为什么 spring jpa 没有删除导致约束错误的行,或者没有一种方法可以使用新角色编辑我的 Account 实体。

我尝试执行的操作涉及以下实体。

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

可以通过一一执行所有操作来解决此问题:首先删除,然后进行新插入。但这应该有更好的方法。

标签: javaspringhibernatejpakotlin

解决方案


实际上“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)

而且我认为您的问题取决于您的级联类图,因此请再次检查它们。


推荐阅读