我需要实现Historization,因为我们必须拥有任何更新记录的新记录。所有记录都有删除和插入的日期。因此,我们所做的是在更新时将删除的日期设置为NOW,并插入插入日期为NOW且删除日期为NULL的新记录。
我使用JPA和eclipseLink作为持久性提供程序。我的问题是,当JPA认为需要更新时,我需要执行“额外”插入。到目前为止,我已在Entity上为非元数据字段设置了updatable = false。我更新了insertDate和deletionDate以及userName。哪一切都按预期工作。我现在需要做的就是制作额外的插页。
我正在尝试使用entityListener来解决这个问题,我实现了@postUpdate和@preUpdate。我无法让它工作,因为如果我尝试提交我在@postUpdate上执行的新事务,我最终陷入僵局。如果我不创建一个新的EntityManager和一个事务,但仅仅在现有的EntityManager上调用持久化由于某种原因,“new”实体没有任何反应。
以下代码:
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");
}
}
答案 0 :(得分:2)
Eclipselink通过添加@Customizer
内置了对历史记录的支持。
有关如何使用它的示例,请参阅此链接:
答案 1 :(得分:1)
请看hibernate envers project。它解决了逆转任务 - 保存有关变更审计的信息。但它可以存储适合您的任务格式的信息。