Come posso accedere ai campi pigri-caricato dopo che la sessione è chiuso, usando Hibernate?

StackOverflow https://stackoverflow.com/questions/1069310

  •  21-08-2019
  •  | 
  •  

Domanda

considerare questo scenario:

  • Ho caricato un'entità genitore attraverso hibernate
  • Parent contiene una raccolta di bambini che è grande e caricato in modo pigro
  • La sessione Hibernate è chiusa dopo questo caricamento iniziale mentre l'utente visualizza i dati padre
  • L'utente può scegliere di visualizzare il contenuto della collezione bambini pigri
  • Ora desidero che la raccolta caricare

Quali sono i modi / miglior modo di carico questa collezione?

  • Si supponga session-in-vista non è un'opzione come il recupero della collezione bambini sarebbe accaduto solo dopo che l'utente ha visto il padre e ha deciso di vedere i figli.
  • Questo è un servizio che sarà accessibile da remoto da web client e desktop basato su.

Grazie.

È stato utile?

Soluzione

Sto facendo alcune ipotesi su ciò che l'utente sta guardando, ma sembra che si desidera solo recuperare i bambini se l'utente ha già visualizzato il genitore e vuole vedere i bambini in realtà.

Perché non prova ad aprire una nuova sessione e andare a prendere i bambini dai loro genitori? Qualcosa sulla falsariga di ...

criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();

Altri suggerimenti

La collezione pigro può essere caricato utilizzando Hibernate.initialize (parent.getCollection ()) tranne che l'oggetto padre ha bisogno di essere collegato a una sessione attiva.

Questa soluzione prende il genitore Entità ed il nome del campo pigro-caricato e restituisce l'entità con la collezione a pieno carico.

Purtroppo, come deve essere riattaccato alla sessione di recente apertura il genitore, non posso utilizzare un riferimento alla raccolta pigro quanto ciò riferimento la versione distaccata dell'Ente; quindi la nomeCampo e la riflessione. Per lo stesso motivo, questo deve restituire il controllante allegato.

Quindi, nello scenario OP, questa chiamata può essere effettuata quando l'utente sceglie di vedere la collezione pigro:

Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName");

Il Metodo:

public Entity initialize(Entity detachedParent,String fieldName) {
    // ...open a hibernate session...
    // reattaches parent to session
    Entity reattachedParent = (Entity) session.merge(detachedParent); 

    // get the field from the entity and initialize it
    Field fieldToInitialize = detachedParent.getClass().getDeclaredField(fieldName);
    fieldToInitialize.setAccessible(true);
    Object objectToInitialize = fieldToInitialize.get(reattachedParent);

    Hibernate.initialize(objectToInitialize);
    return reattachedParent;
}

Hibernate gestisce le collezioni in un modo diverso che i campi normali.

Al mio lavoro si ottiene intorno a questo solo l'inizializzazione dei campi nel caricamento iniziale che abbiamo bisogno su un caso per caso. Ad esempio, in un metodo di carico facciata che è circondato da una transazione potrebbe essere:

public Parent loadParentWithIntent1(Long parentId)
{
  Parent parent = loadParentFromDAO();

  for (Child c : parent.getChildren())
  {
    c.getField1();
  }
}

e noi abbiamo una chiamata facciata diverso per ogni intento. Questo realizza in sostanza ciò che è necessario perché saresti caricare questi campi specifici quando si ha bisogno di loro in qualsiasi modo e questo solo li mette nella sessione in fase di caricamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top