首页 文章

Hibernate Envers复合主键relatedId请求

提问于
浏览
0

我使用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 回答

  • 1

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

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

    也就是说,您可以使用一种解决方法来避免更改复合ID设置 . 我们的想法是创建一个隐藏composite-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 之类的东西来保持各种阴影属性与它们的对象对应部分对齐 .

相关问题