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

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

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

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

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,然后使用reflection来获取所需的私有集合,然后对其进行迭代。

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

发现@nakosspy帖非常有用。 受他的post的启发,我添加了这个非常简单的实用方法,它输出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); } }