我的應用程序使用SpringBoot,Hibernate和Spring Data JPA來實現魔術。我試圖將Hibernate的Envers庫添加到這個版本上,以進行修訂跟蹤。但是,我遇到了Envers和@Version註釋之間的一些衝突。在Envers中使用@Version
默認情況下,Envers不會審覈用@Version註釋的任何字段。這對我來說很有意義,因爲@Version只是爲了跟蹤樂觀鎖定,所以我並不需要保留它的修訂歷史記錄。
但是,我遇到的問題是,當我得到一個修訂實體時,它不會回來的版本。這是有道理的 - Envers將修訂實體存儲在..._ AUD表中,並且該表沒有版本列,所以顯然該實體不具有版本。問題是我有時想使用該實體作爲另一個事務*的一部分,但因爲它沒有版本,實體被認爲是暫時的,並且引發異常。
所以我有一些不同的解決方案,但他們都不理想,所以我希望得到的最好的方式輸入一些我可以做到這一點:
我可以得到修正實體,然後使用修訂實體中的id進行單獨的存儲庫調用以獲取實際實體,然後使用該實體。這會增加很多複雜性(尤其是在確定使用正確的存儲庫時)以及看起來不必要的額外數據庫調用。
我可以保存版本。這並不理想,因爲它不是我真正關心的信息,但如果它意味着一個有效的工作系統,我可以處理它。我也試過這個,並且遇到了問題(在我的配置中將doNotAuditOptimsticLockingField設置爲true似乎什麼也不做),但如果確定這是最好的解決方案,我會打開一個單獨的問題來處理它。
我可能會更改未能使用ID而非實際實體的存儲庫調用,但如果必須更改一些其他存儲庫調用以使其工作,我不會感到驚訝。
如果有第四種選擇,我全部耳朵!
*:另一個事務是將實體轉換爲由REST端點返回的資源時發生的數據庫調用。我有一個實體是AccountEntity。修訂實體我得到的是使用這種方法:
LinkOwnerEntity findByAccountEntity(AccountEntity accountEntity);
而且linkOwner實體類看起來是這樣的:
public class LinkOwnerEntity {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ACCOUNT_ID", unique=true, foreignKey = @ForeignKey(name = "FK_OWNER_ACCOUNT_ID"))
private AccountEntity accountEntity;
...
}
我對這裏所需功能的理解只是用戶需要讀取數據,而不是修改或恢復數據。這將通過通常可用的途徑單獨完成。儘管如此,你確實很重要,我會驗證這個功能是不需要的。但是,如果不需要,我認爲Version字段沒有其他需要。 – EaterOfFromage
用戶代碼實際上不應該習慣於使用'@ Version'屬性來做任何事情。 – Naros
如果這裏的最終目標是恢復一個實體,那應該歸結爲首先要求Hibernate提供一個基於PK的管理實體(如果一個實體仍然存在),然後使用該PK來請求Envers進行特定修訂。然後OP需要將所有_changed_屬性覆蓋到託管實例,然後合併。如果實體已經被刪除並且不使用自然鍵,那麼版本的概念在這裏是不相關的,因爲新實例將被分配一個新的代理鍵並且將被完全視爲新的實體。 – Naros