2013-05-07 13 views
31

Używam danych źródłowych JPA w moim projekcie. Gram z milionami płyt. Mam wymaganie, w którym muszę pobierać dane dla różnych tabel i budować obiekt, a następnie malować go w interfejsie użytkownika. Teraz, jak osiągnąć to moje repozytoria danych wiosennych. Czytałem, że można to osiągnąć dzięki nazwanym natywnym zapytaniom.Wiosenne dane WZP: W jaki sposób kwerenda mogą zwracać obiekty nie będące obiektami lub listę obiektów?

Jeśli nazwane zapytanie rodzimy nie zwraca podmiotowi lub listę podmiotów, możemy odwzorować wynik zapytania do prawidłowego typ zwracany przez pomocą adnotacji @SqlResultSetMapping.

Ale gdy próbuję użyć @SqlResultSetMapping że podejmuje kolejną entityResult. Oznacza to, że rozumiem, że jest to tylko transformacja niektórych wyników zapytania do zestawu wyników jednostki, ale chcę zestaw wyników obiektów nie-obiektów.

@SqlResultSetMapping(
    name="studentPercentile", 
    entities={ 
     @EntityResult(
      entityClass=CustomStudent.class, 
       fields={ 
        @FieldResult(name="id", column="ID"), 
        @FieldResult(name="firstName", column="FIRST_NAME"), 
        @FieldResult(name="lastName", column="LAST_NAME") 
       }   
     ) 
    } 
) 
@NamedNativeQuery(
    name="findStudentPercentile", 
    query="SELECT * FROM STUDENT", 
    resultSetMapping="studentPercentile") 

W powyższym przykładzie jestem po prostu próbuje uzyskać wyniki studenta jednostki w innym POJO „CustomStudent”, która nie jest jednostką. (Ten przykład, który próbuję wykonać tylko dla celów POC, rzeczywisty przypadek użycia jest bardzo skomplikowany, ze skomplikowanym zapytaniem zwracającym inny zestaw wyników).

Jak osiągnąć powyższy przypadek? Czy jest jakiś inny sposób poza użyciem kwerendy o nazwę, którą moja metoda repozytorium zwraca Obiekty nie będące obiektami?

+0

Ostatnio spotkałem się z tym samym problemem i cieszę się, że ktoś napisał i dostałem rozwiązanie również! –

Odpowiedz

23

Byłem bardzo zaskoczony, gdy pierwszy raz spotkałem się z tym, ale tak, można mapować wyniki zapytania za pomocą @SqlResultSetMapping tylko do skalarów i jednostek zarządzanych.

Najlepsze, co możesz zrobić, to chyba pominąć automatyczne mapowanie. Zapytanie bez odwzorowania zwróci List<Object[]> i będzie można je odwzorować tak, jak potrzebujesz.

Innym podejściem byłoby użycie klasy @MappedSuperclass. Klasą oznaczoną jako @MappedSuperclass (CustomStudent w twoim przypadku) może być (nie jestem pewien 100%) używane w @SqlResultSetMapping. ale musisz wprowadzić hierarchię dziedziczenia, to znaczy, że twój Student musi rozszerzyć CustomStudent. To by ssać większość czasu od prawidłowego projektowania OO, ponieważ dziedziczenie byłoby trochę sztuczny ...

+0

Masz na myśli prymitywne typy? – Alex78191

+1

Możesz użyć ConstructorResult https://stackoverflow.com/a/42942353/4854931 – Alex78191

21

Można zrobić coś

@NamedQuery(name="findWhatever", query="SELECT new path.to.dto.MyDto(e.id, e.otherProperty) FROM Student e WHERE e.id = ?1") 

Następnie obiekt MyDto byłoby wystarczy zdefiniowany konstruktor z właściwymi polami, tj.

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; } 
+0

czy mogę napisać coś w stylu 'SELECT new path.to.dto.MyDto (e.id, new path.to.dto.OtherDto)' – masSdev

+0

Nie, ale w twoim MyDto możesz mieć właściwość OtherDto iw konstruktorze MyDto możesz ustawić właściwość OtherDto używając danych przekazanych do konstruktora MyDto. Lub możesz użyć adnotacji @SqlResultSetMapping. – tlavarea

+0

Kiedy to piszę, kompilacja kończy się niepowodzeniem z 'Sprawdzanie poprawności nie powiodło się dla zapytania dla metody public abstract..' –

17

Co z JPA 2.1 ConstructorResult?

@SqlResultSetMapping(
    name="studentPercentile", 
    classes={ 
     @ConstructorResult(
      targetClass=CustomStudent.class, 
      columns={ 
       @ColumnResult(name="ID"), 
       @ColumnResult(name="FIRST_NAME"), 
       @ColumnResult(name="LAST_NAME") 
      } 
     ) 
    } 
) 

@NamedNativeQuery(name="findStudentPercentile", query="SELECT * FROM STUDENT", resultSetMapping="studentPercentile") 
+0

Witaj, to brzmi nieźle, ale NamedQuery wciąż musi być dołączony do i Entity by być częścią jednostki wytrwałości? – romainbsl

Powiązane problemy