0

我使用Hibernate Envers進行審計,並且遇到了複合主鍵的問題。基於相關屬性,我有許多具有複合主鍵的實體。構造如下:Hibernate Envers複合主鍵relatedId請求

@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

這裏的問題是,Envers基本不註冊@Id註解的類型,這也正是爲什麼你遇到了這個錯誤的關係。

不幸的是,Hibernate 4.3不再被維護,因此我們所做的任何錯誤修復都適用於Hibernate 5.x,最有可能只是5.2.x.

也就是說,有一種解決方法可以用來避免必須更改您的composite-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以保持各種陰影屬性與其對象的對應部分對齊。

+1

我在這裏添加了一個與本次討論相關的JIRA:https://hibernate.atlassian.net/browse/HHH-11748 – Naros

+1

對此的修復很簡單。我們只需要能夠對標識符執行第二遍就像我們對非標識符屬性鏈接關聯和組件屬性一樣。 – Naros