私は、古き良き恐ろしいTransientObjectException
.
私の質問は、現在の Hibernate セッションにあるすべてのオブジェクトのリストを取得する方法はありますか?
この質問に対する回答が得られるまでに、おそらく現在の問題は解決しているでしょうが、いずれにせよ、セッションのすべてを一覧表示できることは、次に発生したときに非常に役立つでしょう。
Hibernate はその内部を公開しないため、パブリック API で探しているものを見つけることはできません。ただし、 Hibernateインターフェイスの実装クラスで答えを見つけることができます。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 の新しいリリースによってブレーキがかかる可能性があります。
@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);
}
}