【问题标题】:java hibernate envers set other primary key for audit tablejava hibernate envers为审计表设置其他主键
【发布时间】:2017-05-07 13:29:57
【问题描述】:

我想在 JPA Hibernate 中映射一个 Map。设置看起来像

@Entity(name = "reservation")
@Table(name = "reservation")
@Access(AccessType.FIELD)
@Audited
public class ReservationEntity {

  // other fields

  @ElementCollection(fetch = FetchType.EAGER)
  @MapKeyColumn(name = "discountType")
  @Column(name = "discountAmount")
  @CollectionTable(
          name="discountTypeAndAmount",
          joinColumns=@JoinColumn(name="reservation_id")
  )
  private Map<DiscountType, BigDecimal> discountTypeAndAmount;

}

我可以第一次将实体写入数据库,但是当我更新实体时,entitymanager.getTransaction().commit() 出现以下错误:

Caused by: javax.persistence.EntityExistsException: A different object with
the same identifier value was already associated with the session : 
[discountTypeAndAmount_AUD#{REV=DefaultRevisionEntity(id = 3, 
revisionDate = Dec 20, 2016 8:52:45 PM), element=10.00,  
ReservationEntity_reservation_id=1, mapkey=CASE_STUDY}]

在例外情况下,CASE_STUDY 是枚举之一。 discountTypeAndAmount_AUD 是自动生成的审计日志表。

审计表 discountTypeAndAmount 似乎是使用由 REV(修订 ID)、reservation_iddiscountTypediscountAmount 组成的复合键生成的,并且由于 envers 没有引发错误不知道如何处理 BigDecimal 作为主键的一部分。

是否有注释将审计表的主键设置为仅由 REV(修订 ID)、reservation_iddiscountType 组成的组合?由于该字段无论如何都是一个映射,因此确实不需要将discountAmount 作为主键的一部分。

【问题讨论】:

    标签: java mysql hibernate jpa


    【解决方案1】:

    @MapKeyColumn 用于指定 key 列的映射,如果 key 是基本类型,但我不确定,但我猜 DiscountType 本身就是实体,所以你需要使用 @MapKeyJoinColumn 映射你的 key。

    【讨论】:

    • 他的key是一个枚举(来自上一篇文章),而XXXColumn注解用于指定列名,而不是某个东西是否是表PK的一部分
    • 如果key是Enum,那么他应该用@MapKeyEnumerated来映射它。
    • 我也尝试添加@MapKeyEnumerated,但没有任何影响。 MapKeyColumn 实际上适用于主连接表。只是在应用 @Audited 标志时,envers 的审计表有问题
    • 如果你的映射键是枚举的,它是存储在数据库中的序数还是字符串?
    • 好像存储为int(11)
    猜你喜欢
    • 2023-03-24
    • 2012-05-08
    • 1970-01-01
    • 2015-02-22
    • 2018-09-19
    • 2015-08-20
    • 1970-01-01
    • 2015-12-14
    • 2012-12-05
    相关资源
    最近更新 更多