Как можно сопоставить результирующий набор запроса с другим объектом, кроме таблицы - PullRequest
1 голос
/ 28 января 2020

Я пытаюсь получить данные из базы данных и сопоставить их с другим объектом, но я получаю

java.lang.IllegalArgumentException: java.lang.ArrayIndexOutOfBoundsException: 0

Моя таблица выглядит как

@Entity
@Table(name = "Student")
@NamedNativeQueries({
    @NamedNativeQuery(name = "findAll", query = "Select a.student_id as id, a.student_code as code from Student a")
    })
public class Student {

    @Id
    private Long student_id;
    private String student_code;
    private String student_user_id;
    private String student_first_name;

    //Some other fields, getters and setters
}

Моя BO выглядит как

@Entity
public class Generic{

    @Id
    private Long id;
    private String code;
    private String user_id;

    //getters and setters
}

Мой класс вызовов DAO примерно такой

Query query = entityManager.createNamedQuery("findAll", Generic.class);
query.getResultList();

Я получаю исключение на

entityManager.createNamedQuery("findAll", Generic.class);

Это трассировка стека, которую я имею

    Caused by: java.lang.IllegalArgumentException: java.lang.ArrayIndexOutOfBoundsException: 0
at org.hibernate.internal.AbstractSharedSessionContract.buildQueryFromName(AbstractSharedSessionContract.java:774)
at org.hibernate.internal.AbstractSharedSessionContract.createNamedQuery(AbstractSharedSessionContract.java:869)
at org.hibernate.internal.AbstractSessionImpl.createNamedQuery(AbstractSessionImpl.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:301)
at com.sun.proxy.$Proxy157.createNamedQuery(Unknown Source)

1 Ответ

1 голос
/ 28 января 2020

Я пытаюсь получить данные из БД и сопоставить их с другой сущностью, но я получаю ArrayIndexOutOfBoundsException

Но в следующей строке вы этого не делаете, вы пытаясь получить список Student списка сущностей. А какая у вас другая сущность здесь?

entityManager.createNamedQuery("findAll", Student.class);

Но так как вы предоставили другую сущность Generic, я предполагаю, что вы хотите, чтобы в нее загружались ваши данные. Существуют разные возможные решения этой проблемы. Давайте разберемся.

Использование SELECT NEW ключевых слов

Обновите свой собственный запрос на этот

@NamedNativeQueries({
    @NamedNativeQuery(name = "Student.findAll", query = "SELECT NEW Generic(a.student_id, a.student_code) FROM Student a")
})

Вы должны определить конструктор в Класс Generic, который квалифицирует этот вызов

public void Generic(Long id, String code) {
     this.id = id;
     this.code = code;
}

И обновите выполнение запроса в DAO как

List<Generic> results = em.createNamedQuery("Student.findAll" , Generic.class).getResultList();

Примечание: Возможно, у вас есть поместить полный путь к классу Generic в запросе для этой конструкции

из List<Object[]>

В качестве альтернативы, простое и простое решение получит список результатов как список Object[] и заполнить любой новый объект, который вы хотите.

List<Object[]> list = em.createQuery("SELECT s.student_id, s.student_code FROM Student s")
                        .getResultList(); 

for (Object[] obj : list){
    Generic generic = new Generic();
    generic.setId(((BigDecimal)obj[0]).longValue());
    generic.setCode((String)obj[1]);
}
...