【问题标题】:Eclipselink history of related objects相关对象的 Eclipselink 历史
【发布时间】:2014-07-30 08:39:47
【问题描述】:

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

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

HistoryCustomizer 是这样的:

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”提示获取历史对象

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);

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

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

【问题讨论】:

    标签: jpa eclipselink


    【解决方案1】:

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

    我在代码的其他部分使用 JPA,所以我将从将 JPA Query 转换为 EclipseLink ReadAllQuery 开始。

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

            // 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());
            }
    

    【讨论】:

    • 我可以使用 AS_OF 提示来删除历史记录吗
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    相关资源
    最近更新 更多