我可以使用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)从过去获取相关对象?
答案 0 :(得分:5)
为了查询几个实体的历史状态 - 不仅仅是上面的实体 - 我们必须创建一个 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());
}