我需要實現歷史化,因爲我們必須爲任何更新的記錄創建新記錄。所有記錄都有一個刪除並插入的日期。因此,我們所做的是在更新時將已刪除的日期設置爲NOW,並插入插入日期爲NOW並刪除日期爲NULL的新記錄。使用JPA進行歷史記錄
我使用JPA和eclipseLink作爲持久提供者。我的問題是,當JPA認爲需要更新時,我需要執行「額外」插入操作。到目前爲止,我已經在非元數據字段的實體上設置了updatable = false。我更新了插入日期和刪除日期以及用戶名。哪一個按預期工作。我現在需要做的就是製作額外的插頁。
我想解決這個問題,使用entityListener,其中我實現@postUpdate和@preUpdate。如果我嘗試提交我在@postUpdate上執行的新事務,那麼我無法使其工作,因爲我最終陷入僵局。如果我沒有創建一個新的EntityManager和一個事務,而僅僅是在現有的EntityManager上持續存在調用,出於某種原因,「新」實體不會發生任何事情。下面
代碼:
import java.util.Calendar;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PostPersist;
import javax.persistence.PostUpdate;
import javax.persistence.PreUpdate;
public class ColorEntityListener {
public ColorEntityListener()
{
}
@PreUpdate
void onPreUpdate(ColorEntity c)
{
System.out.println("onPreUpdate");
c.setDeletionDate(Calendar.getInstance());
}
@PostUpdate
void onPostUpdate(ColorEntity c)
{
System.out.println("onPostUpdate");
createNewRecord(c);
}
@PostPersist
void onPostPersist(ColorEntity c)
{
System.out.println("onPostPersist");
}
private void createNewRecord(ColorEntity c) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("v2_tl");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
ColorEntity cNew = new ColorEntity();
cNew.setPrNumber(c.getPrNumber());
cNew.setHs(c.getHs());
cNew.setCountryCode(c.getCountryCode());
cNew.setValidFrom(c.getValidFrom());
cNew.setValidUntil(c.getValidUntil());
cNew.setColorCode(c.getColorCode());
//cNew.setId(0);
cNew.setInsertDate(Calendar.getInstance());
cNew.setDeletionDate(null);
em.persist(cNew);
System.out.println("Before commit of new record");
em.getTransaction().commit();
System.out.println("After commit of new record");
}
}
插入和刪除日期是多餘的,如果由於某種原因刪除日期與下一個插入日期之間存在間隙,可能會導致您遇到麻煩。特別是如果你在你的例子中設置日期,因爲不同的方法可能會在'Calendar.getInstance()'返回一個接一個的值時執行。 – SpaceTrucker 2015-03-03 08:18:16
相關:http://stackoverflow.com/questions/9542366/how-to-implement-a-temporal-table-using-jpa – SpaceTrucker 2015-03-03 08:22:39
顯然,在完成的例子中,我將日曆設置爲本地對象,並將其用於兩者聲明。我很好奇,但是如何指示刪除的行沒有刪除日期? – Michael 2015-03-03 12:59:26