Eclipselink相关对象的历史记录 [英] Eclipselink history of related objects

查看:96
本文介绍了Eclipselink相关对象的历史记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用HistoryCustomizer创建实体的历史记录

I can create history of an entity with a HistoryCustomizer

@Entity
@Customizer(MyHistoryCustomizer.class)
public class Employee {..}

HistoryCustomizer就是这样的:

the HistoryCustomizer is something like this one:

public class MyHistoryCustomizer implements DescriptorCustomizer {
    public void customize(ClassDescriptor descriptor) {
        HistoryPolicy policy = new HistoryPolicy();
        policy.addHistoryTableName("EMPLOYEE_HIST");
        policy.addStartFieldName("START_DATE");
        policy.addEndFieldName("END_DATE");
        descriptor.setHistoryPolicy(policy);
    }
}

可以通过"AS_OF"提示获取历史对象

The history objects can be fetched with the "AS_OF" hint

javax.persistence.Query historyQuery = em
                    .createQuery("SELECT e FROM Employee e", Employee.class)
                    .setParameter("id", id)
                    .setHint(QueryHints.AS_OF, "yyyy/MM/dd HH:mm:ss.SSS")
                    .setHint(QueryHints.READ_ONLY, HintValues.TRUE)
                    .setHint(QueryHints.MAINTAIN_CACHE, HintValues.FALSE);

很好,但是,如果您开始访问此历史对象引用的对象,则引用的对象将是它们的实际版本.因此,去年的Employee(通过历史查询获取)将分配有当前地址,而不再是去年的地址.

just fine BUT, if you start accessing objects referenced by this historical object, the referenced objects will be the actual version of them. So the Employee from last year (fetched by a historical query) will have the current Address assigned to it and no the one it used to have last year.

如何告诉EclipseLink(2.5.0)也从过去获取相关对象?

How can I tell EclipseLink (2.5.0) to fetch the related object from the past as well?

推荐答案

为了查询多个实体的历史状态-不仅仅是上面的实体,我们必须创建一个 EclipseLink特定的HistoricalSession .在此会话中运行的查询将使用相同的历史时间戳,并表示对象图的正确历史状态.

In order to query the historical state of several - not just one like above - entities, we have to create an EclipseLink specific HistoricalSession. Queries run through this session will use the same historical timestamp and represent the proper historical state of the object graph.

我在代码的其他部分中使用了JPA,因此我将从将JPA查询转换为EclipseLink ReadAllQuery开始.

I am using JPA in other parts of the code, so I will start with converting the JPA Query to an EclipseLink ReadAllQuery.

HistoricalSession具有自己的实体缓存,因此历史实体不会与普通实体混合.

The HistoricalSession has its own entity cache, so that the historical entities do not mix with the normal ones.

        // Get the EclipseLink ServerSession from the JPA EntitiyManagerFactory
        Server serverSession = JpaHelper.getServerSession(emf);
        // Only a ClientSession can give us a HistoricalSession so ask one from the ServerSession 
        ClientSession session = serverSession.acquireClientSession();
        // Create the HistoricalSessions. A HistoricalSession is sticked to a point in the past and all the queries are executed at that time.
        Session historicalSessionAfterFirstChild = session.acquireHistoricalSession(new AsOfClause(afterFirstChildAdded));

        ReadAllQuery q; 

        Query jpaQuery = em.createQuery(query);
        jpaQuery.setParameter("root", "parent");
        // Extract the EclipseLink ReadAllQuery from the JPA Query. We can use named queries this way.
        q=JpaHelper.getReadAllQuery(jpaQuery);

        // This is a possible EclipseLink bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=441193
        List<Object> arguments = new Vector<Object>();
        arguments.add("parent");
        q.setArgumentValues(arguments);

        Vector<Parent> historyAwareParents ;

        // Execute the query
        historyAwareParents = (Vector<Parent>) historicalSessionAfterFirstChild.executeQuery(q);
        for (Child c : historyAwareParents.get(0).children) {
            System.out.println(c.getExtension() + " " + c.getRoot());
        }

这篇关于Eclipselink相关对象的历史记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆