2013-07-27 16 views
6

Widziałem kilka podobnych pytań z 0 dobrymi odpowiedziami.JPA chce załadować kolekcje FetchType.LAZY

To powinno być bardzo proste. Używam Java JPA i chcę ładować listę elementów podrzędnych czasami, ale nie cały czas. Niestety, JPA nie wydaje się mnie słuchać, kiedy mówię, żeby leniwie go sprowadzić. W 100% upewniłem się, że w moim kodzie nie ma nigdzie żadnego atrybutu childEntities. Jednak wszystkie elementy podrzędne wciąż są ładowane natychmiast po wywołaniu funkcji JPA.em(). Find (..). Tak deklaruję związek z adnotacjami.

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

I to jest jak załadować podmiot nadrzędny:

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

Dodatkowo, miałem nadzieję, że czasami chętni pobrać tę kolekcję i być w stanie dynamicznie powiedzieć JPA kiedy to zrobić. Ale to jest krok 2. Krok 1 to po prostu to działa.

+1

Jak się weryfikacji, że to naciągane? Czy istnieje możliwość ustawienia odwzorowań orm.xml lub innych mapowań miejsc lub detektorów jednostek, które zastępują ustawienie leniwy lub uruchamiają kolekcję? Z jakiego operatora korzystasz? – Chris

+0

W debugerze widzę zaraz po wywołaniu wyszukiwania, że ​​lista jest wypełniona. Nie używam żadnego XML-a do konfiguracji, tylko adnotacje. –

+0

Na razie stworzyłem niezwykle nadęty i hacky rozwiązanie. Stworzyłem dwie jednostki nadrzędne, jedną z kolekcją listy podrzędnej i jedną bez. Niestety, ten hack (tak jak wiele hacków) powoduje kaskadę brudu do reszty mojego kodu. –

Odpowiedz

4

Zrobiłem w ten sposób. Proszę odnieść to będzie pracować doskonale overthere też:

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


    } 

Zastosowanie @OneToOne(fetch = FetchType.LAZY....) za mapowanie jeden do jednego i do użytku zbiórki @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 

} 

Jeżeli chcesz uzyskać dostęp do kolekcji, łączenia przed i uzyskać obiektu:

@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

Spróbuję tego, gdy dostanę trochę wolnego czasu w tym tygodniu. Dzięki. –

+0

serdecznie zapraszamy! – Rajesh

+0

czy możesz powiedzieć dlaczego używasz łączenia w getMemberWithMemberDetails? – iku

2

jestem aktywnie poszukują odpowiedzi na twój # 2: Wprowadzenie WZP do leniwego rzeczy i czasami obciążenia niecierpliwie innym razem.

Jeśli chodzi o twoje # 1 pytanie brzmi dla mnie, że chcesz użyć getReference() zamiast find(). Jeśli używasz Hibernuj, to utworzy odniesienie do obiektu, a następnie tylko dostanie je, gdy będzie potrzebne.

Jestem pewien, że to pomoże: When to use EntityManager.find() vs EntityManager.getReference()