【问题标题】:Hibernate Envers: Auditing with Embedded class in Composite KeyHibernate Envers:使用复合键中的嵌入式类进行审计
【发布时间】:2019-07-22 05:33:45
【问题描述】:

我正在尝试使用 Hibernate Envers(当前版本:5.4.1.Final)激活对 JPA 实体的审核。

问题:实体有一个复合键 (@EmbeddedId),而键类本身有一个 @Embedded 类。我没有让@Audit 工作。

问题:是什么导致了这里的问题,您能否提出解决方案/解决方法?

示例: 数据库使用跨所有表的公共数据空间的概念。表 item 可能包含以下列:dataspace1, dataspace2, dataspace3, itemid, value1, value2, ...。当然,正如 Hibernate Envers 所期望的那样,存在一个审计表 item_aud

我有以下课程:

@Entity
@Table(name = "item")
@Audited
public class Item {
    @EmbeddedId 
    private ItemKey itemKey;

    @Column(name = "value1")
    private String value1;

    @Column(name = "value2")
    private String value2;
    ...
}    

@Embeddable
public class ItemKey {
    @Embedded 
    private DataSpace dataSpace;

    @Column(name = "itemid")
    private String itemId;
}

@Embeddable
public class DataSpace {
    @Column(name = "dataspace1")
    private String dataSpace1;

    @Column(name = "dataspace2")
    private String dataSpace2;

    @Column(name = "dataspace3")
    private String dataSpace3;
}

使用此设置我得到一个异常:org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType

@Audit 被停用时,保存/加载实体可以正常工作。当我将三个DataSpace 属性平放在ItemKey 中时,它也可以工作。不过,我们更喜欢具有单独 DataSpace 类的解决方案,因为它在其他实体之间共享。

【问题讨论】:

  • 考虑到您的 cmets,不幸的是,这听起来像是一个错误。
  • 确实如此。如果这是一个错误,我们将不胜感激任何解决方法的建议:-)
  • 可以ItemKey 简单地扩展DataSpace(认为在这种情况下您需要将@MappedSuperclass 添加到DataSpace)?

标签: hibernate jpa composite-primary-key hibernate-envers embeddable


【解决方案1】:

鉴于您的 cmets,这似乎是一个错误。

我认为扩展而不是组合应该可以工作。

虽然 JPA 规范没有明确规定应该支持扩展 Embeddable 类,但 Hibernate确实支持这种结构。

您还应该能够保留 get/set 方法,因此不必更改客户端代码。

@MappedSuperclass
@Embeddable
public class DataSpace {
    @Column(name = "dataspace1")
    private String dataSpace1;

    @Column(name = "dataspace2")
    private String dataSpace2;

    @Column(name = "dataspace3")
    private String dataSpace3;
}

@Embeddable
public class ItemKey extends DataSpace {

    @Column(name = "itemkey")
    private String itemKey;

    public void setDataSpace(DataSpace dataSpace){
        //copy to the inherited fields
    }

    public DataSpace getDataSpace(){
        DataSpace dataSpace = new DataSpace();
        //populate form the inherited fields

        return dataSpace;
    }
}

【讨论】:

  • 感谢您提出这种方法。它在技术上有效!不幸的是,我们失去了获取/设置DataSpace 实例的可能性,例如myItem.getKey().setDataSpace(myDataSpace)
  • 这些方法还是可以的。只需复制到 set 上的各个字段或返回从 get 上的字段填充的新实例。
猜你喜欢
  • 2018-04-18
  • 2019-11-16
  • 2023-03-24
  • 2017-09-13
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 2017-07-09
  • 2015-12-14
相关资源
最近更新 更多