如何在Many端使用@OneToMany和@EmbeddedId配置Envers

问题描述 投票:0回答:2

我有一个

User
实体和
UserCompanyRole
实体。
UserCompanyRole
有一个复合主键。每个
User
可以有多个角色。我知道应该避免使用复合主键,并且实际上我已经用 id 列替换了它,但我仍然想知道是我的代码有问题还是 Envers 有问题。下面代码的结果是启动时出错。知道出了什么问题吗?:

由以下原因引起:javax.persistence.PersistenceException:[PersistenceUnit: 默认]无法构建Hibernate SessionFactory;嵌套异常是 org.hibernate.MappingException:实体映射中的重复列: domain.usercompany.UserCompanyRole_AUD 列:user_id(应该是 映射为 insert="false" update="false")

文件

User.java

@Audited(withModifiedFlag = true, modifiedColumnName = "user_company_roles_mod")
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id", insertable = false, updatable = false)
@AuditMappedBy(mappedBy = "user")
private List<UserCompanyRole> userCompanyRoles = new ArrayList<>();

文件

UserCompanyRole.java

@EmbeddedId
private UserCompanyRoleId userCompanyRoleId;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
@Audited
private User user;

文件

UserCompanyRoleId.java

@Embeddable
public class UserCompanyRoleId implements Serializable {

@Column(name = "company_id")
private Long companyId;

@Column(name = "user_id")
private Long userId;

@Column(name = "role")
private String role;
java spring hibernate jpa hibernate-envers
2个回答
-1
投票

我会尝试使用 insert = "false" update = "false" 映射 User,因为您设置它的位置位于 User 实体中。

使用您的代码,您将在 UserCompanyRole 实体中拥有两个 user_id,即 EmbeddedId 之一和审核字段之一,因为您将用于查询的 id 之一,请注意审核字段之一字段插入=“假”更新=“假”。


-1
投票

我之前遇到过这个问题,与您上面描述的类似关系。我不认为这与恩弗斯有关,因为我没有使用恩弗斯,但我看到了与你所看到的类似的例外情况。我想您可以通过暂时删除 @Audited 和 @AuditMappedBy 注释来测试这一点,并查看 UserCompanyRole 与 UserCompanyRole_AUD 是否会遇到类似的异常?

为了避免“映射中重复列”错误,您可能需要尝试以下操作:

  1. 从 User.userCompanyRoles 中删除 @JoinColumn 注释
  2. 将删除的@JoinColumn注释移动到UserCompanyRole.user
  3. 如果上述步骤不起作用,请将 UserCompanyRole @JoinColumn 转换为 @JoinFormula,如下所示:
@EmbeddedId
private UserCompanyRoleId userCompanyRoleId;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
@JoinFormula(value = "user_id", referencedColumnName= "<user pk column name>")
@Audited
private User user;

公式方法阻止 Hibernate 在映射中添加另一个“user_id”列。

我假设用户有一个简单的 ID/主键,因为没有提到。如果它也是复合的,你将需要类似以下的东西:

    @JoinColumnsOrFormulas(value = {
            @JoinColumnOrFormula(formula = @JoinFormula(value = "tid", referencedColumnName = "tid")),
            @JoinColumnOrFormula(column = @JoinColumn(name = "delegate_id", referencedColumnName = "id",
                    updatable = false, columnDefinition = ENTITY_ID_DEF,
                    foreignKey = @ForeignKey(name = "fk_delegation_identity")))
    })

© www.soinside.com 2019 - 2024. All rights reserved.