1

我有一个实体。该实体在事务中被修改。但在某些时候,我想知道在交易期间对该实体所做的更改。这样做的原因是触发对实体的更改的差异导出。我已经开发了这个“解决方案”:

public void triggerExport(A a)
{
    em.detach(a);
    A result = em.find(A.class, a.internId);

    doExport(a, result);
    em.merge(a);

}

我不确定这是否真的是一种可行的方法。它会为此实体的每次比较导致额外的数据库交互。你怎么看?有没有更好的办法?

4

3 回答 3

3

您还可以创建一个新的 EntityManager 并找到该对象,这将节省分离和合并对象。

如果您使用的是 EclipseLink,您可以从 EntityManager 中解开 UnitOfWork 并调用 getCurrentChanges() 以获取在事务中所做的更改的更改集。如果使用共享缓存,您还可以使用 getOriginalVersionOfObject() 来获取原始对象。

EclipseLink 也有完整的历史支持,

见, http://wiki.eclipse.org/EclipseLink/Examples/JPA/History

于 2012-06-19T14:46:56.710 回答
2

I have not used this personally, but heard good things about JBoss Envers , which is a auditing tool integrated with Hibernate. You may be able to use this for auditing what has changed for an entity, and exporting the specific changes.

于 2012-06-19T12:58:39.460 回答
0

如果您使用 Hibernate,默认情况下它使用一级缓存来缓存默认情况下在同一会话中进行的可重复查询。

来自Hibernate Recipes: A Problem-Solution Approach book

一级缓存处于事务级别或工作单元。它在 Hibernate 中默认启用。第一级缓存与会话相关联。如果在同一个会话中多次执行同一个查询,则与该查询关联的数据被缓存。

假设您在会话中多次检索一个对象:Hibernate 查询数据库的次数是否与调用该查询的次数一样多?

Session session = factory.openSession();
try {
Book book1 = (Book) session.get(Book.class, id);
Book book2 = (Book) session.get(Book.class, id);
} finally {
session.close();
}

如果您检查 Hibernate 执行的 SQL 语句,您会发现只进行了一次数据库查询。这意味着 Hibernate 在同一个会话中缓存你的对象。这种缓存称为一级缓存,其缓存范围是一个会话。

于 2012-06-19T12:33:44.133 回答