2013-05-07 3 views
31

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

Если именованный родной запрос не возвращает объект или список сущностей, мы можем отобразить результат запроса к правильному типу возвращаемого по использованию @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") 

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

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

+0

Недавно я столкнулся с той же проблемой и рад видеть, что кто-то опубликовал и получил решение для этого! –

ответ

23

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

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

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

+0

Вы имеете в виду примитивные типы? – Alex78191

+1

Вы можете использовать ConstructorResult https://stackoverflow.com/a/42942353/4854931 – Alex78191

21

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

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

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

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

Могу ли я написать что-то вроде 'SELECT new path.to.dto.MyDto (e.id, new path.to.dto.OtherDto)' – masSdev

+0

Нет, но в вашем MyDto у вас может быть свойство OtherDto, а в конструкторе MyDto вы можете установить свойство OtherDto, используя данные, переданные в конструктор MyDto. Или вы можете использовать аннотацию @SqlResultSetMapping. – tlavarea

+0

Когда я пишу это, компиляция не выполняется с 'Validation failed для запроса для метода public abstract..' –

17

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

Здравствуйте, это звучит неплохо, но NamedQuery еще нужно привязать, а Entity - частью единицы постоянства? – romainbsl

 Смежные вопросы

  • Нет связанных вопросов^_^