2015-04-21 22 views
6

mam następujące 2 klasy (okrojone do tego postu)Hibernate Projekcje/Lazy Loading dla non wymagane od 1 do 1 Mappings

public class ApplicationVO implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -3314933694797958587L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    private Integer id; 


    @OneToOne(fetch = FetchType.LAZY, mappedBy = "application") 
    @Cascade({ CascadeType.ALL }) 
    @JsonIgnore 
    private ApplicationHomeScreenVO applicationHomeScreen; 

... 
... 
... 
} 


public class ApplicationHomeScreenVO implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -9158898930601867545L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    @JsonProperty("id") 
    private Integer id; 

    @OneToOne(fetch = FetchType.LAZY) 
    @Cascade({ CascadeType.SAVE_UPDATE }) 
    @JoinColumn(name="application_id") 
    @JsonProperty("application") 
    protected ApplicationVO application;  

    ... 
    ... 
    ... 
} 

Próbuję załadowania applicationById wuthout ładowania applicationHomeScreen Niestety leniwy ładowanie nie wydaje się działać. Mam spojrzał na innych stanowiskach i zalecamy ustawienie opcji = false flag na adnotacją @OneToOne ale niestety applicationHomeScreen może być opcjonalnie

Jestem teraz próbuje użyć projekcje ale to nie działa albo do mnie albo

Kiedy zadzwonić następującą metodę

public ApplicationVO findApplicationById(Integer applicationId) { 

     Criteria criteria = currentSession().createCriteria(ApplicationVO.class); 
     criteria.add(Restrictions.eq("id", applicationId)); 

     criteria.setProjection(Projections.projectionList() 
       .add(Projections.property("applicationHomeScreen"), "applicationHomeScreen")) 
       .setResultTransformer(Transformers.aliasToBean(ApplicationVO.class)); 

     ApplicationVO applicationVO = (ApplicationVO) criteria.uniqueResult(); 

     return applicationVO; 
    } 

uzyskać ślad stosu

java.lang.ArrayIndexOutOfBoundsException: 0 
    at org.hibernate.loader.criteria.CriteriaLoader.getResultRow(CriteriaLoader.java:168) 
    at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:148) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:754) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:953) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:921) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) 
    at org.hibernate.loader.Loader.doList(Loader.java:2554) 
    at org.hibernate.loader.Loader.doList(Loader.java:2540) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) 
    at org.hibernate.loader.Loader.list(Loader.java:2365) 
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682) 
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380) 
    at org.hibernate.internal.CriteriaImpl.uniqueResult(CriteriaImpl.java:402) 
    at com.dao.database.impl.ApplicationDAOImpl.findApplicationById(ApplicationDAOImpl.java:349) 

Czy ktoś może polecić AP miałaby znajdować mogę używać albo a) dostać leniwy załadunku działa poprawnie na jeden do jednego mapowania gdzie nie jest wymagana stowarzyszenie b) uzyskać projekcje robocze, więc nie trzeba ładować żadnych skojarzeń dziecka, jeżeli nie są one potrzebne

podziękowaniem Ci Damien

+0

Zastanawiam się, czy ktoś k W jaki sposób mogę to osiągnąć za pomocą prognoz? –

+0

Może to trochę pomóc: http://ankursinghal86.blogspot.in/2014/07/one-to-one-and-lazy-vs-eager-loading.html – Arpit

+0

Czy naprawdę potrzebujesz połączenia dwukierunkowego? –

Odpowiedz

2

Jedynym rozwiązaniem jest następujące kroki:

  1. Dodaj @LazyToOne do związku jeden do jednego:

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "application") 
    @Cascade({ CascadeType.ALL }) 
    @JsonIgnore 
    @LazyToOne(value = LazyToOneOption.NO_PROXY) 
    private ApplicationHomeScreenVO applicationHomeScreen; 
    
  2. Konfiguracja bytecode enhancement

1

opcjonalne @OneToOne relacje nie może być leniwy, ponieważ zakaz posiadania boku związek nie teraz, czy dziecko istnieje (opcjonalnie) - Hibernate nie wie, czy umieścić obiekt proxy lub null. Istnieje kilka sposobów obejścia tego problemu. Ten link ma szczegółowe wyjaśnienie niektórych obejściach

+0

Widziałem te opcje już wiwaty - niektóre z nich nie są atrakcyjne. Czy powinienem ograniczyć wyniki za pomocą prognoz? –

+0

Możesz użyć transformacji wyników tak, jak próbujesz i wybierz tylko niestandardowe kolumny z db, a następnie zwróć ten niestandardowy komponent bean, ale to kolejna rzecz (nie będziesz pracować z rzeczywistym obiektem - jest to odpowiednie w niektórych przypadkach). – isah

+0

Tak, wiem co masz na myśli. To niestety nie zadziałało z moim mapowaniem - czy wiesz dlaczego? –

Powiązane problemy