Hibernate:如何获取会话中当前所有对象的列表

时间:2013-05-09 11:33:30

标签: java hibernate

我正在获得好的,旧的和可怕的TransientObjectException,并且,正如在这种情况下经常发生的那样,我在查找代码中的哪种细微错误导致问题时遇到了问题。

我的问题是:有没有办法获取当前Hibernate会话中每个对象的列表?

当我得到这个问题的答案时,我可能已经解决了当前的问题,但是,无论如何,能够列出会话的所有内容在下一次发生时会有很大的帮助。

2 个答案:

答案 0 :(得分:16)

Hibernate不会向公众公开其内部,因此您无法在公共API中找到您要搜索的内容。但是,您可以在Hibernate接口的实现类中找到答案: 此方法(取自http://code.google.com/p/bo2/source/browse/trunk/Bo2ImplHibernate/main/gr/interamerican/bo2/impl/open/hibernate/HibernateBo2Utils.java)将告知会话中是否存在对象:

public static Object getFromSession
        (Serializable identifier, Class<?> clazz, Session s) {              
    String entityName = clazz.getName();
    if(identifier == null) {
       return null;
    }      
    SessionImplementor sessionImpl = (SessionImplementor) s;
    EntityPersister entityPersister = sessionImpl.getFactory().getEntityPersister(entityName);
    PersistenceContext persistenceContext = sessionImpl.getPersistenceContext();
    EntityKey entityKey = new EntityKey(identifier, entityPersister, EntityMode.POJO);
    Object entity = persistenceContext.getEntity(entityKey);
    return entity;
    }

如果向下钻取一点,您将看到PersistenceContext的唯一实现是org.hibernate.engine.StatefulPersistenceContext。 该类具有以下集合:

// Loaded entity instances, by EntityKey
private Map entitiesByKey;

// Loaded entity instances, by EntityUniqueKey
private Map entitiesByUniqueKey;

// Identity map of EntityEntry instances, by the entity instance
private Map entityEntries;

// Entity proxies, by EntityKey
private Map proxiesByKey;

// Snapshots of current database state for entities
// that have *not* been loaded
private Map entitySnapshotsByKey;

// Identity map of array holder ArrayHolder instances, by the array instance
private Map arrayHolders;

// Identity map of CollectionEntry instances, by the collection wrapper
private Map collectionEntries;

// Collection wrappers, by the CollectionKey
private Map collectionsByKey; //key=CollectionKey, value=PersistentCollection

// Set of EntityKeys of deleted objects
private HashSet nullifiableEntityKeys;

// properties that we have tried to load, and not found in the database
private HashSet nullAssociations;

// A list of collection wrappers that were instantiating during result set
// processing, that we will need to initialize at the end of the query
private List nonlazyCollections;

// A container for collections we load up when the owning entity is not
// yet loaded ... for now, this is purely transient!
private Map unownedCollections;

// Parent entities cache by their child for cascading
// May be empty or not contains all relation 
private Map parentsByChild;

因此,您需要做的是将PersistenceContext转换为StatefulPersistenceContext,然后使用反射来获取所需的私有集合,然后对其进行迭代。

我强烈建议您仅在调试代码时这样做。这不是公共API,它可以通过更新版本的Hibernate来制动。

答案 1 :(得分:10)

发现@nakosspy帖非常有用。受他的帖子的启发,我添加了这个非常简单的实用方法,它输出了Hibernate Session的内容。

正如nakosspy所说,这仅用于调试目的,因为它是一个HACK。

    public static void dumpHibernateSession(Session s) {
    try {
        SessionImplementor sessionImpl = (SessionImplementor) s;
        PersistenceContext persistenceContext = sessionImpl.getPersistenceContext();
        Field entityEntriesField = StatefulPersistenceContext.class.getDeclaredField("entityEntries");
        entityEntriesField.setAccessible(true);
        IdentityMap map = (IdentityMap) entityEntriesField.get(persistenceContext);
        log.info(map);
    } catch (Exception e)
    {
        log.error(e);
    }

}
相关问题