首页 > 解决方案 > 如何在多端使用 @OneToMany 和 @EmbeddedId 配置 Envers

问题描述

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

引起:javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build 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;

标签: javaspringhibernatejpahibernate-envers

解决方案


我之前遇到过这个问题,与您上面描述的关系类似。我认为它与 Envers 无关,因为我没有使用 Envers,但我看到了与您所看到的类似的例外情况。我想您可以通过暂时删除 @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")))
    })


推荐阅读