Hibernate Envers复合主键relatedId请求

时间:2017-05-15 15:49:36

标签: hibernate primary-key composite-primary-key hibernate-envers auditing

我使用Hibernate Envers进行审核,并且复合主键存在问题。基于相关属性,我有许多具有复合主键的实体。结构如下:

@Entity
@Audited
@Table(indexes = { @Index(columnList = "person_id"),
        @Index(columnList = "document_id") })
public class PersonDocument implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private Document document;

    @Id
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private Person person;

该关系不是双向注释的。主键在审计表中使用正确,就像envers描述它的文档一样。

但现在我不是所有与人有关的修订。以下是:

final AuditQuery query = AuditReaderFactory.get(entityManager)
                .createQuery().forRevisionsOfEntity(PersonDocument.class, false, true)
                .add(AuditEntity.relatedId("person").eq("12"))
                .addOrder(AuditEntity.revisionNumber().desc());

然后我收到以下错误:

This criterion can only be used on a property that is a relation to another property.

如果我使用非复合主键,那么它运行没有问题,但是我得到了错误。有谁有想法?将数据从复合主键迁移到多个实体的额外主键并不容易。

我使用Hibernate版本4.3.11

祝你好运

1 个答案:

答案 0 :(得分:1)

这里的问题是Envers基本上没有注册@Id注释类型的关系,这正是你遇到这个错误的原因。

不幸的是,Hibernate 4.3不再被维护,因此我们所做的任何错误修复此时都适用于Hibernate 5.x,很可能只是5.2.x。

也就是说,您可以使用一种解决方法来避免更改复合ID设置。我们的想法是创建一个隐藏复合ID键值的属性,并为这些查询使用shadowed属性。

@Entity
@Audited
public class PersonDocument implements Serializable {
  @Id
  @ManyToOne(optional = false)
  private Document document; // lets assume this maps to document_id
  @Id
  @ManyToOne(optional = false)
  private Person person; // lets assume this maps to person_id

  // we'll shadow those properties now
  @Column(name = "document_id", nullable = false, insertable = false, updatable = false)
  private Integer documentId;

  @Column(name = "person_id", nullable = false, insertable = false, updatable = false)
  private Integer personId;
}

现在,我们可以基于简单的属性进行查询,而不是使用relatedId方法:

reader.createQuery().forRevisionsOfEntity( PersonDocument.class, false, true )
  .add( AuditEntity.property( "personId" ).eq( 42 ) )
  .addOrder( AuditEntity.revisionNumber().desc() );

显然这不太理想,但你当然可以使用像@PostUpdate@PostPersist之类的东西来保持各种阴影属性与它们的对象对应部分对齐。