2013-05-09 4 views
13

私は良い、古い、恐ろしいTransientObjectExceptionを得ています。このような場合によく起こるように、私はどのような微妙なバグコード内に問題が発生しています。Hibernate:現在セッションにあるすべてのオブジェクトのリストを取得する方法

私の質問です:現在の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; 

だから、あなたがStatefulPersistenceContextへのPersistenceContextをキャストされて何をする必要があるか、そしてあなたが望むプライベートコレクションを取得するためにリフレクションを使用して、それを繰り返します。

デバッグコードでのみ行うことを強くお勧めします。これは公開されたAPIではなく、新しいリリースのHibernateによってブレーキをかけることができます。

+0

ありがとうございます;問題が次回発生したときに多くの助けになります。 ;) –

9

非常に便利な@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); 
    } 

} 
+1

hibernate 4.3.11では、 'StatefulPersistenceContext.class.getDeclaredField(" entitiesByKey ");'を使用して 'Map'(または' entityEntries'が存在しないので他のフィールド)として保存する必要があります。それ以外はコンセプトは堅実です。 – jlb

関連する問題