2013-05-09 6 views
13

Ich bekomme die gute, alte und gefürchtete TransientObjectException, und, wie so oft in diesem Fall passiert, habe ich Probleme zu finden, was für ein kleiner Fehler im Code verursacht das Problem.Hibernate: wie bekomme ich eine Liste aller Objekte in der Sitzung

Meine Frage ist: Gibt es eine Möglichkeit, eine Liste aller Objekte in der aktuellen Hibernate-Sitzung zu erhalten?

Ich werde wahrscheinlich das aktuelle Problem gelöst haben, bis ich eine Antwort für diese Frage bekomme, aber sowieso, in der Lage zu sein, alles aufzulisten, was die Sitzung ist, würde viel in der nächsten Zeit helfen, die passiert.

Antwort

12

Hibernate stellt seine Interna nicht der Öffentlichkeit zur Verfügung, so dass Sie in der öffentlichen API nicht finden, wonach Sie suchen. Jedoch Sie Ihre Antwort in den Implementierungsklassen der Hibernate-Schnittstellen finden: Diese Methode (aus http://code.google.com/p/bo2/source/browse/trunk/Bo2ImplHibernate/main/gr/interamerican/bo2/impl/open/hibernate/HibernateBo2Utils.java) wird zeigen, ob ein Objekt in der Sitzung vorhanden ist:

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

Wenn Sie ein wenig mehr Drill-down, werden Sie Beachten Sie, dass die einzige Implementierung von PersistenceContext org.hibernate.engine.StatefulPersistenceContext ist. Diese Klasse hat die folgenden Sammlungen:

// 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; 

Also, was Sie tun müssen, ist die PersistenceContext zu einem StatefulPersistenceContext gegossen, dann Reflektion verwenden, um die private Sammlung zu erhalten, die Sie wollen, und dann auf sie iterieren.

Ich empfehle dringend, dass Sie nur das Debugging-Code tun. Dies ist keine öffentliche API und könnte durch neuere Versionen von Hibernate gebremst werden.

+0

Danke; Das wird beim nächsten Mal sehr hilfreich sein. ;) –

9

Gefunden @nakosspy Beitrag sehr nützlich. Inspiriert von seinem Beitrag habe ich diese sehr einfache Hilfsmethode hinzugefügt, die den Inhalt von Hibernate Session ausgibt.

Wie nakosspy sagte, dies ist nur für Debugging Zwecke, da es ein HACK ist.

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

Für Hibernate 4.3.11 müssen Sie 'StatefulPersistenceContext.class.getDeclaredField (" entitiesByKey ");' verwenden und als 'Map' speichern (oder ein anderes Feld, da' entityEntries' nicht existiert) - aber Abgesehen davon ist das Konzept solide. – jlb

Verwandte Themen