2013-05-09 44 views
13

我越来越好,老害怕TransientObjectException,并且,在这种情况下经常发生的,我有问题的定位是什么样微妙的bug在代码中导致了这个问题。休眠:如何获取当前会话中的所有对象的列表

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

我可能已经解决了的时候,我得到一个答案这个问题当前的问题,但是,无论如何,能够列出一切,是会议将有很大的帮助在接下来发生的时间。

回答

12

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的更新版本。

+0

感谢;这会在下一次发生问题时提供帮助。 ;) – 2013-05-09 12:53:12

9

找到@nakosspy文章非常有用。受他的文章启发,我添加了这个非常简单的实用方法,输出Hibernate Session的内容。

由于nakosspy说,这是仅用于调试的目的,因为它是一个黑客。

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

} 
+1

对于hibernate 4.3.11,您需要使用'StatefulPersistenceContext.class.getDeclaredField(“entitiesByKey”);'并将其存储为'Map'(或其他字段,因为'entityEntries'不存在) - 但除了这个概念是坚实的。 – jlb 2017-03-30 09:52:34