有没有办法获取当前在实体管理器中附加的所有对象?
我想写一些监控代码,它会报告附加对象及其类的数量
意味着查找先前查询加载的所有对象并在实体管理器中查找操作
我正在使用EclipseLink,所以特定的解决方案也很好。
答案 0 :(得分:3)
EclipseLink的JPA接口几乎包含其本机代码,以便EntityManager使用下面的UnitOfWork会话(并且EMF包装ServerSession)。如果您想查看它正在管理的实体,您需要访问UnitOfWork。
如果使用JPA 2.0,则可以使用EntityManager解包方法:
UnitOfWork uow = ((EntityManagerImpl)em).getUnitOfWork();
否则,使用一些演员
printRegisteredObjects()
从那里,UnitOfWork有一个所有已注册(也称为托管)实体的列表。您可以使用UOW使用getCloneMapping().keySet()
方法直接记录其内容,或使用hasDeletedObjects()
自行获取。
您还可以使用getDeletedObjects().keySet()
然后使用hasNewObjectsInParentOriginalToClone()
查看已删除的对象,如果使用getNewObjectsCloneToOriginal().keySet()
和{{1}}
答案 1 :(得分:1)
你可以在很多方面使用JPA我仍然没有意识到,并且在eclipselink中有很多内容我仍然不完全理解,但看起来有可能看到持久性上下文。请自行承担使用此代码的风险。它只是为了给你一个提示,可以检查上下文。 (代码是对还是错我发布它是因为当我试图决定是否使用eclipselink时它会对我有所帮助。对于如何正确执行此操作的文档似乎没有多少。 )
public void saveChanges() {
Date now = new Date();
JpaEntityManager jem = em.unwrap(JpaEntityManager.class);
UnitOfWorkImpl uow = jem.unwrap(UnitOfWorkImpl.class);
// inserts
for (Object entity : uow.getNewObjectsCloneToOriginal().keySet()) {
if (entity instanceof IAuditedEntity) {
IAuditedEntity auditedEntity = (IAuditedEntity) entity;
auditedEntity.setAuditedUserId(this.userId);
auditedEntity.setAuditedAt(now);
auditedEntity.setCreatedAt(now);
}
}
// updates
UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet) uow.getUnitOfWorkChangeSet();
if (uowChangeSet != null) {
List<IAuditedEntity> toUpdate = new ArrayList<>();
for(Entry<Object, ObjectChangeSet> entry : uowChangeSet.getCloneToObjectChangeSet().entrySet()) {
if (entry.getValue().hasChanges()) {
if (entry.getKey() instanceof IAuditedEntity) {
toUpdate.add((IAuditedEntity) entry.getKey());
}
}
}
for (IAuditedEntity auditedEntity : toUpdate) {
auditedEntity.setAuditedUserId(this.userId);
auditedEntity.setAuditedAt(now);
}
}
// deletions
Project jpaProject = uow.getProject();
boolean anyAuditedDeletions = false;
for (Object entity : uow.getDeletedObjects().keySet()) {
if (entity instanceof IAuditedEntity) {
anyAuditedDeletions = true;
DeletedEntity deletion = new DeletedEntity();
deletion.setTableName(jpaProject.getClassDescriptor(entity.getClass()).getTableName());
deletion.setEntityId(((IAuditedEntity) entity).getId());
deletion.setAuditedUserId(this.userId);
em.persist(deletion);
}
}
}
答案 2 :(得分:0)
您可以通过检查MetaModel
上可以从任何EntityManager
获取的实体来实现此目的。
使用示例:
EntityManager em = // get your EM however...
for(EntityType<?> entityType : em.getMetaModel().getEntities())
{
Class<?> managedClass = entityType.getBindableJavaType();
System.out.println("Managing type: " + managedClass.getCanonicalName());
}
此示例将打印出EntityManager管理的所有类类型。要获取所有实际管理的对象,只需在EntityManager上查询该类型的所有对象。
<强>更新强>
从JPA 2.0开始,您可以缓存由javax.persistence.Cache
管理的结果。但是,使用普通JPA无法实际检索存储在缓存中的对象,您可以做的最好的事情是通过Cache.contains(Class cls, Object pk)
检查某个对象是否在缓存中:
em.getEntityManagerFactory().getCache().contains(MyData.class, somePK);
但是,EclipseLink使用Cache
扩展JpaCache
。您可以使用它来实际通过JpaCache.getObject(Class cls, Object id)
从缓存中获取对象。这不会返回任何集合或任何东西,但它是下一个最好的东西。
不幸的是,如果你想真正访问缓存中的对象,你需要自己管理它。
答案 3 :(得分:0)
我在EntityManager
界面中看不到这样的选项。只有contains(Object entity)
方法,但您需要传递conrete对象,并在PersistenceContext中检查它们是否存在。另外看PersistenceContext
界面我没看到这样的选项。