java Hibernate:如何获取当前会话中所有对象的列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16460796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate: how to get a list of all the objects currently in the session
提问by Haroldo_OK
I'm getting the good, old and dreaded TransientObjectException
, and, as often happens in such case, I'm having problems locating what kind of subtle bug in the code is causing the problem.
我得到了好的、旧的和可怕的TransientObjectException
,而且,正如在这种情况下经常发生的那样,我在定位代码中什么样的微妙错误导致了问题时遇到了问题。
My question is: is there a way to obtain a list of every object that's in the current Hibernate session?
我的问题是:有没有办法获得当前 Hibernate 会话中每个对象的列表?
I'll probably have solved the current problem by the time I get an answer for this question, but, anyway, being able to list everything that is the session would help a lot in the next time that happens.
当我得到这个问题的答案时,我可能已经解决了当前的问题,但是,无论如何,能够列出会话中的所有内容将在下次发生时有很大帮助。
回答by nakosspy
Hibernate does not expose its internals to the public, so you won't find what you are searching for in the public API. However you can find your answer in the implementation classes of the Hibernate interfaces: This method (taken from http://code.google.com/p/bo2/source/browse/trunk/Bo2ImplHibernate/main/gr/interamerican/bo2/impl/open/hibernate/HibernateBo2Utils.java) will tell if an object exists in the session:
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;
}
If you drill down a little more, you will see that the only implementation of PersistenceContext is org.hibernate.engine.StatefulPersistenceContext. This class has the following collections:
如果再深入一点,您将看到 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;
So, what you need to do is cast the PersistenceContext to a StatefulPersistenceContext, then use reflection to get the private collection that you want and then iterate on it.
因此,您需要做的是将 PersistenceContext 强制转换为 StatefulPersistenceContext,然后使用反射获取您想要的私有集合,然后对其进行迭代。
I strongly suggest you do that only on debugging code. This is not public API and it could brake by newer releases of Hibernate.
我强烈建议你只在调试代码时这样做。这不是公共 API,它可能会被更新的 Hibernate 版本阻止。
回答by Gaetano Caruana
Found @nakosspy post very useful. Inspired by his post, I added this very simple utility method that outputs the contents of Hibernate Session.
发现@nakosspy 帖子非常有用。受他帖子的启发,我添加了这个非常简单的实用方法,用于输出 Hibernate Session 的内容。
As nakosspy said this is ONLY for debugging purposes as it is a HACK.
正如 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);
}
}