Подтвердить что ты не робот

Spring Данные JPA: Как вернуть Query объекты объектов или список объектов?

Я использую данные JPA в моем проекте. Я играю с миллионами записей. У меня есть требование, когда я должен получать данные для различных таблиц и строить объект, а затем рисовать его в пользовательском интерфейсе. Теперь как это сделать, мои репозитории данных spring. Я прочитал, что это может быть достигнуто с помощью Named native запросов.

Если именованный внутренний запрос не возвращает объект или список объектов, мы можем сопоставить результат запроса с правильным типом возврата на используя аннотацию @SqlResultSetMapping.

Но когда я пытаюсь использовать @SqlResultSetMapping, он принимает еще один entityResult. Я понимаю, что это просто преобразование некоторого результата запроса только в результирующий набор объектов, но я хочу получить набор объектов без объектов.

@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")

В приведенном выше примере я просто пытаюсь получить результаты от учащегося Entity в другое pojo " CustomStudent", который не является сущностью. (Этот пример, который я пытаюсь выполнить только для цели POC, фактический usecase очень сложный, со сложным запросом, возвращающим разные результаты).

Как достичь выше usecase? Есть ли другой способ помимо использования запроса имени, чтобы мой метод репозитория возвращал объекты Non-Entities?

4b9b3361

Ответ 1

Я был глубоко удивлен, когда впервые пришел к этому, но, да, вы можете сопоставлять результаты запроса с помощью @SqlResultSetMapping только для скаляров и управляемых объектов.

Лучшее, что вы можете сделать, я думаю, это пропустить автоматическое сопоставление. Запрос без сопоставления возвратит List<Object[]>, и вы можете сопоставить его так, как вам нужно.

Другим подходом было бы использование @MappedSuperclass. Класс, обозначенный как @MappedSuperclass (CustomStudent в вашем случае), может быть (не уверен, что 100%, хотя) используется в @SqlResultSetMapping. но вам нужно ввести иерархию наследования, то есть ваша студенческая сущность должна расширить CustomStudent. Это будет отсасывать большую часть времени из надлежащего дизайна OO, потому что наследование будет немного искусственным...

Ответ 2

Вы можете сделать что-то вроде

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

Тогда объекту MyDto просто нужен конструктор, определенный с правильными полями i.e.

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

Ответ 3

Как насчет 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")