在 Java Spring 應用程式中,我有一個類似于以下的類:
class MyModel {
// other properties here
private Boolean accessAllowed;
public Boolen isAccessAllowed() {
return accessAllowed;
}
public void setAccessAllowed(Boolean accessAllowed) {
this.accessAllowed = accessAllowed;
}
public void updateAccessAllowedForResponse() {
// business logic to update `accessAllowed` only for read methods of repository
}
public void updateAccessAllowedForSave() {
// business logic to update `accessAllowed` only for write methods of repository
}
}
我們的想法是我們在 DB 中使用三個值,即nullor trueorfalse并使用空值作為“默認值”,即用戶沒有做出選擇。因此,如果 DB 中的值為 null,我們會根據某些業務邏輯回傳true或回傳。false
問題是該值僅用于在“記憶體中”更新回應或其他應用程式區域,但物體中的更改updateAccessAllowedForResponse()不應該在資料庫中持續存在。
目前,我從存盤庫中的 Hibernate 會話中取消附加物體,例如
class MyRepository extends GenericRepository<MyModel> {
public MyModel get(Long id) {
MyModel instance = super.get(id);
Session session = entityManager.unwrap(Session.class);
session.evict(instance);
instance.updateAccessAllowedForResponse();
return instance;
}
public MyModel merge(MyModel instance) {
instance.updateAccessAllowedForSave()
return super.merge(instance);
}
}
這可行,但是上述方法存在一個大問題:我必須在很多地方重復這一點。理想情況下,我希望能夠在 MyModel 本身上定義這個邏輯。也可以選擇使用自定義存盤庫,但這是一個非常具體的用例,我們沒有時間僅為此功能撰寫自定義存盤庫。
老實說,我是 Java / Spring 的新手。所以我希望有一些方法可以通過谷歌搜索找到。
uj5u.com熱心網友回復:
您可以使用 Spring 事務來完成此操作,方法是創建兩個單獨的保存方法,一個有 Spring Transactional,isolation = Isolation.SERIALIZABLE另一個沒有。所以你說的是你想強迫用戶使用特定的保存點,不管他們是否想在事務中用不同的物件做其他事情,或者不。在這種情況下,強制提交,重繪 ,呼叫yourPersistenceService.saveSecondaryObject(x)什么的,然后你說yourPersistenceService.savePrimaryObject(y)總是需要在之前呼叫。或者,對于 MyModel 物件,通過更新觸發方法進行預保存和后保存。這應該由 Hibernate 自動發生,因此您有機會在其中跟蹤該欄位的更改,并在持久化后設定該欄位。這與我在只讀欄位中遇到的情況相同,這些欄位只需要為輸出而復制(資料庫是 Postgres 12,我創建了一個復制表,它只是在廉價觸發器上將事務復制從一個復制到只讀表。在這樣,每次模型更改時,它都會觸發 Postgres 上的作業以更新表)。
public MyModel get(Long id) {
MyModel instance = super.get(id);
Hibernate.initialize(instance.accessAllowed);
instance.flush();
return instance;
}
作為第三種選擇,您可以讓控制器處理所有這些,接收 JPA 物件,設定欄位,然后將其發送到 JSP,而無需重繪 或重新加載任何內容。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/485709.html
