如何在EntityManager(JPA)中查找所有托管连接对象
是否有方法获取实体管理器中当前附加的所有对象?如何在EntityManager(JPA)中查找所有托管连接对象,jpa,eclipselink,entitymanager,Jpa,Eclipselink,Entitymanager,是否有方法获取实体管理器中当前附加的所有对象? 我想编写一些监控代码,用于报告附加对象及其类的数量。 这意味着查找由以前的查询加载的所有对象,并将查找操作放入实体管理器。 我使用的是EclipseLink,所以一个特定的解决方案也很好。您可以通过检查元模型上的实体来实现这一点,可以从任何EntityManager获得 用法示例: EntityManager em = // get your EM however... for(EntityType<?> entityType : em
我想编写一些监控代码,用于报告附加对象及其类的数量。
这意味着查找由以前的查询加载的所有对象,并将查找操作放入实体管理器。
我使用的是EclipseLink,所以一个特定的解决方案也很好。您可以通过检查
元模型上的实体来实现这一点,可以从任何EntityManager
获得
用法示例:
EntityManager em = // get your EM however...
for(EntityType<?> entityType : em.getMetaModel().getEntities())
{
Class<?> managedClass = entityType.getBindableJavaType();
System.out.println("Managing type: " + managedClass.getCanonicalName());
}
但是,EclipseLink使用JpaCache
扩展了Cache
。您可以使用它通过从缓存中实际获取对象。这不会返回一个集合或任何东西,但它是下一个最好的东西
不幸的是,如果您想实际访问缓存中的对象,您需要自己管理。我在EntityManager
界面中没有看到这样的选项。只有一个方法,但是您需要传递conrete对象,并且它们在PersistenceContext中被检查是否存在。同样在界面上,我看不到这样的选项。EclipseLink的JPA界面几乎包装了它的本机代码,使得EntityManager在下面使用UnitOfWork会话(EMF包装了一个ServerSession)。如果您想查看UnitOfWork正在管理哪些实体,则需要访问UnitOfWork
如果使用JPA 2.0,则可以使用EntityManager展开方法:
UnitOfWork uow = em.unwrap(UnitOfWork.class);
否则,使用一些铸件
UnitOfWork uow = ((EntityManagerImpl)em).getUnitOfWork();
从那里,UnitOfWork有一个所有已注册(也称为托管)实体的列表。您可以使用UOW使用printRegisteredObjects()
方法直接记录它拥有的内容,或者使用getCloneMapping().keySet()
自己获取它
您还可以使用hasDeletedObjects()
然后使用getdeletedbjects().keySet()
查看删除的对象(如果有),使用hasNewObjectsInParentOriginalToClone()
和getnewobjectsconetooriginal().keySet()查看新对象也是如此
你可以用很多我还不知道的方式使用JPA,在eclipselink中有很多我还不完全理解的事情,但看起来可以看到持久性上下文。使用此代码的风险自负。它只是想给你一个提示,提示你可以检查上下文。(无论代码是对是错,我都会发布它,因为当我试图决定是否使用eclipselink时,它会帮助我。关于如何正确使用eclipselink,文档中似乎没有太多内容。)
public void saveChanges(){
现在日期=新日期();
JpaEntityManager jem=em.unwrap(JpaEntityManager.class);
UnitOfWorkImpl uow=jem.unwrap(UnitOfWorkImpl.class);
//插入
对于(对象实体:uow.GetNewObjectSCOneToOriginal().keySet()){
if(IAuditedEntity的实体实例){
IAuditedEntity auditedEntity=(IAuditedEntity)实体;
setAuditedUserId(this.userId);
setAuditedAt(现在);
setCreatedAt(现在);
}
}
//更新
UnitOfWorkChangeSet uowChangeSet=(UnitOfWorkChangeSet)uow.getUnitOfWorkChangeSet();
if(uowChangeSet!=null){
List toUpdate=new ArrayList();
对于(条目:uowChangeSet.getCloneToObjectChangeSet().entrySet()){
if(entry.getValue().hasChanges()){
if(IAuditedEntity的entry.getKey()实例){
添加((IAuditedEntity)条目.getKey());
}
}
}
对于(IAAuditedEntity auditedEntity:toUpdate){
setAuditedUserId(this.userId);
setAuditedAt(现在);
}
}
//删除
项目jpaProject=uow.getProject();
布尔值anyAuditedElections=false;
对于(对象实体:uow.getDeletedObjects().keySet()){
if(IAuditedEntity的实体实例){
anyAuditedElections=true;
DeletedEntity deletation=新的DeletedEntity();
deletation.setTableName(jpaProject.getClassDescriptor(entity.getClass()).getTableName());
deletation.setEntityId(((IAuditedEntity)entity.getId());
删除.setAuditedUserId(this.userId);
em.persist(删除);
}
}
}
谢谢你的详细回答,但我想问些别的问题。我想查找已从以前的精细/查询操作加载到实体管理器中的所有附着对象。加载到实体管理器是什么意思?这不是EM管理的所有对象类型吗?不是。如果我做了一个从类a返回100个对象的查询和另一个加载100个类B对象的查询,它们都由实体管理器管理。我想在内存中迭代这200个对象。现在我理解了你的问题,相应地更新了我的答案。不幸的是,没有很好的方法可以做到这一点,但为什么不重新运行您的查询呢?因为对象是缓存的,所以它的速度与运行一些缓存.getAllObjects()
方法一样快。我们是很多开发人员,一旦加载了大量对象,实体管理器的操作就会明显变慢。我需要编写代码来监控大型事务并发现潜在问题。
UnitOfWork uow = ((EntityManagerImpl)em).getUnitOfWork();
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);
}
}
}