【问题标题】:How to configure Envers with @OneToMany and @EmbeddedId on the Many side如何在多端使用 @OneToMany 和 @EmbeddedId 配置 Envers
【发布时间】:2023-03-12 19:35:01
【问题描述】:

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

引起:javax.persistence.PersistenceException: [PersistenceUnit: default] 无法构建 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


    【解决方案1】:

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

    使用您的代码,您将在 UserCompanyRole 实体中有两个 user_id,一个是 EmbeddedId,另一个是审核字段,因为您将用于查询的一个是 id,请注意其中一个审计字段为 insert = "false" update = "false"。

    【讨论】:

    • 我试过了,但没有帮助。这不是@MapsId("userId") 的用途吗?正如您在错误中看到的,UserCompanyRole 实体不是问题,而是 Envers 使用的审计:UserCompanyRole_AUD。我仍然不确定 Envers 是否不能将 @AuditMappedBy 与复合键一起处理,或者我映射的东西有误
    【解决方案2】:

    我之前遇到过这个问题,与您上面描述的关系类似。我认为它与 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")))
        })
    
    

    【讨论】:

      猜你喜欢
      • 2016-09-06
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 2021-12-27
      • 2013-03-15
      相关资源
      最近更新 更多