2013-07-27 14 views
6

Ho visto diverse domande simili con 0 buone risposte.JPA è impaziente di caricare le raccolte secondarie FetchType.LAZY

Questo dovrebbe essere molto semplice. Sto usando Java JPA e voglio caricare un elenco di entità figlio a volte, ma non sempre. Sfortunatamente, l'APP non sembra ascoltarmi quando dico di prenderlo pigramente. Ho reso sicuro al 100% che non c'è un posto nel mio codice in cui l'attributo childEntities sia accessibile in alcun modo. Tuttavia, tutte le entità figlio vengono ancora caricate immediatamente dopo la chiamata a JPA.em(). Find (..). Questo è il modo in cui dichiaro la relazione con le annotazioni.

@Entity 
@Table(name = "parentEntities") 
public class ParentEntity implements Serializable { 
    .... 
    @OneToMany(mappedBy = "entityPropertyName", fetch = FetchType.LAZY) 
    public List<ChildEntity> childEntities; 
    ... 
} 

e questo è come mi carico la controllante:

ParentEntity parentEntity = JPA.em().find(ParentEntity.class, id); 

Inoltre, speravo di volte ansiosi prendere questa collezione e in grado di dire in modo dinamico APP quando a farlo. Questo è il passaggio 2 però. Il passaggio 1 è solo per farlo funzionare correttamente.

+1

Come stai verificando che sia inverosimile? Esiste un orm.xml o altre mappature di luoghi o possono essere impostati listener di entità che sovrascrivono l'impostazione lazy o attivano la raccolta? Quale fornitore stai usando? – Chris

+0

Nel debugger posso vedere subito dopo la chiamata di ricerca che l'elenco è popolato. Non sto usando alcun XML per la configurazione, solo annotazioni. –

+0

Per ora ho creato una soluzione estremamente prolissa e hacky. Ho creato due entità padre, una con la raccolta dell'elenco figlio e l'altra senza. Sfortunatamente, questo hack (come fanno molti hack) riversa la sporcizia nel resto del mio codice. –

risposta

4

Ho fatto in questo modo. Si prega di fare riferimento questo, si dovrà lavorare ottimamente overthere troppo:

@Entity 
@Table(name = "member_information") 
    public class MemberInformation implements Serilizable{ 

    @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE},optional = false) 
     private MemberInformationDetails memberInformationDetailsId; 


    @LazyCollection(LazyCollectionOption.TRUE) 
     @OneToMany(mappedBy = "memberInformationId", cascade = CascadeType.ALL) 
     private Collection<AccountOpening> accountOpeningCollection; 


    } 

Usa @OneToOne(fetch = FetchType.LAZY....) per mappatura uno a uno e per l'uso raccolta @LazyCollection(LazyCollectionOption.TRUE).

@Entity 
@Table(name = "member_info_details") 
public class MemberInformationDetails implements Serializable{ 

@OneToOne(mappedBy = "memberInformationDetailsId") 
    private MemberInformation memberInformationId; 

.......//getter and setters 

} 


@Entity 
@Table(name = "account_opening") 
public class AccountOpening implements Serializable { 

@JoinColumn(name = "member_information_id", referencedColumnName = "id", nullable = false) 
    @ManyToOne(optional = false) 
    private MemberInformation memberInformationId; 

..........//getters and setters 

} 

Quando si vuole accedere alla raccolta, unire prima e ottenere l'oggetto:

@Stateless 
public class MemberInformationFacade{ 
.............. 
    public MemberInformation getMemberWithMemberDetails(MemberInformation m) { 
     m = getEntityManager().merge(m); 
     try { 
      m.getMemberInformationDetailsId().getId(); 


      m.getMemberInformationDetailsId().accountOpeningCollection().size(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return m; 
    } 

} 
+0

Ci proverò quando avrò del tempo libero questa settimana. Grazie. –

+0

siete i benvenuti! – Rajesh

+0

puoi dire perché usi l'unione in getMemberWithMemberDetails? – iku

2

Sto cercando attivamente per la risposta alla vostra # 2: ottenere APP a roba carico pigri a volte e con entusiasmo altre volte.

Per quanto riguarda la tua domanda numero 1, mi sembra che tu voglia usare getReference() invece di find(). Se stai usando Hibernate, creerà un riferimento dell'oggetto e poi lo prenderà solo quando è necessario.

Sono sicuro che questo vi aiuterà: When to use EntityManager.find() vs EntityManager.getReference()

Problemi correlati