2016-01-19 3 views
2

Есть ли способ получить все объекты, которые в настоящее время прикреплены в диспетчере сущностей?
Я хочу написать некоторый контрольный код, который будет сообщать количество подключенных объектов и их классов.
Значение нахождения всех объектов, которые были загружены предыдущими запросами, и найти операции в диспетчере сущностей.
Я использую EclipseLink, поэтому особое решение тоже хорошо.Как найти все управляемые прикрепленные объекты в EntityManager (JPA)

ответ

2

Интерфейс JPA EclipseLink довольно сильно обертывает свой собственный код таким образом, что EntityManager использует подкласс UnitOfWork под ним (и EMF обертывает ServerSession). Вам нужно попасть в UnitOfWork, если вы хотите увидеть, какие объекты он управляет.

При использовании JPA 2.0, вы можете использовать метод Unwrap EntityManager:

UnitOfWork uow = em.unwrap(UnitOfWork.class); 

иначе, использовать некоторые отливку

UnitOfWork uow = ((EntityManagerImpl)em).getUnitOfWork(); 

Оттуда UnitOfWork есть список всех зарегистрированных (иначе управляемый). Вы можете использовать UOW для прямого входа в систему, используя метод printRegisteredObjects(), или получить его самостоятельно, используя getCloneMapping().keySet().

Вы можете также видеть удаленные объекты с помощью hasDeletedObjects(), а затем getDeletedObjects().keySet(), если таковой имеется, так как и то же самое для новых объектов с использованием hasNewObjectsInParentOriginalToClone() и getNewObjectsCloneToOriginal().keySet()

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.


Update:

На 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). Это не возвращает коллекцию или что-то еще, но это лучшая вещь.

К сожалению, если вы хотите фактически получить доступ к объектам в кеше, вам нужно будет управлять этим самостоятельно.

+0

Спасибо за подробный ответ, но я просил что-то еще. Я хочу найти все прикрепленные объекты, уже загруженные в диспетчер сущности из предыдущих операций fine/queries. –

+0

Что вы подразумеваете под * загруженным в диспетчер объектов *? Разве это не все объекты, которые принадлежат типу, который управляет ЭМ? –

+0

Нет. Если бы я выполнил запрос, который возвратил 100 объектов из класса A и другой запрос, который загружал 100 объектов класса B, все они управляются менеджером сущностей. Я хочу итерировать эти 200 объектов в памяти. –

0

Я не вижу такой опции в интерфейсе EntityManager. Существует только метод contains(Object entity), но вам нужно передать объекты-стили, и они проверены на существование в PersistenceContext. Также глядя на интерфейс PersistenceContext, я не вижу такой опции.

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

 Смежные вопросы

  • Нет связанных вопросов^_^