Hibernate Envers复合主键relatedId请求
Hibernate Envers composite primary key relatedId request
我使用 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
此致
这里的问题是 Envers 基本上不为 @Id
注释类型注册关系,这正是您 运行 进入此错误的原因。
不幸的是,Hibernate 4.3 不再维护,因此我们所做的任何错误修复目前都适用于 Hibernate 5.x,很可能只有 5.2.x.
也就是说,您可以使用一种解决方法来避免必须更改复合 ID 设置。这个想法是,您创建一个 属性 来隐藏复合 ID 键值,并使用隐藏的 属性 进行这些查询。
@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
之类的东西来保持各种阴影属性与其对象对应部分对齐。
我使用 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
此致
这里的问题是 Envers 基本上不为 @Id
注释类型注册关系,这正是您 运行 进入此错误的原因。
不幸的是,Hibernate 4.3 不再维护,因此我们所做的任何错误修复目前都适用于 Hibernate 5.x,很可能只有 5.2.x.
也就是说,您可以使用一种解决方法来避免必须更改复合 ID 设置。这个想法是,您创建一个 属性 来隐藏复合 ID 键值,并使用隐藏的 属性 进行这些查询。
@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
之类的东西来保持各种阴影属性与其对象对应部分对齐。