использование entityManager.createNativeQuery (query, foo.class)

Я хотел бы вернуть список целых чисел из

javax.persistence.EntityManager.createNativeQuery звонок

Почему следующее неверно?

entityManager.createNativeQuery("Select P.AppID From P", Integer.class);

в частности, почему я получаю «... Неизвестный объект: java.lang.Integer»

Придется ли мне создать класс сущности с единственным полем, которое является целым числом?

Спасибо


person Jim Ward    schedule 21.01.2010    source источник


Ответы (5)


То, что вы делаете, называется проекцией. Это когда вы возвращаете только скалярное значение, принадлежащее одной сущности. Вы можете сделать это с помощью JPA. См. скалярное значение.

Думаю, в этом случае можно вообще опустить тип сущности:

   Query query = em.createNativeQuery(  "select id from users where username = ?");  
   query.setParameter(1, "lt");  
   BigDecimal val = (BigDecimal) query.getSingleResult(); 

Пример взят из здесь.

person ewernli    schedule 21.01.2010
comment
Да, по моей оплошности 2-й параметр мне не понадобился. Все еще не понимал, почему это не сработало. Я должен это решить. Спасибо - person Jim Ward; 21.01.2010
comment
Лучше использовать именованные параметры вместо? - person Omar Al Kababji; 11.04.2013

Это не работает, потому что второй параметр должен быть сопоставленной сущностью и, конечно, Integer не является постоянным классом (поскольку на нем нет аннотации @Entity).

вам следует сделать следующее:

Query q = em.createNativeQuery("select id from users where username = :username");
q.setParameter("username", "lt");
List<BigDecimal> values = q.getResultList();

или если вы хотите использовать HQL, вы можете сделать что-то вроде этого:

Query q = em.createQuery("select new Integer(id) from users where username = :username");
q.setParameter("username", "lt");
List<Integer> values = q.getResultList();

С Уважением.

person Omar Al Kababji    schedule 21.01.2010
comment
Для JPA есть ли способ при использовании собственного запроса указать, как вы хотите преобразовать скалярное значение? Я хотел бы использовать List<Integer> values = q.getResultList(); как-нибудь без цикла и создания новых целых чисел. - person Snekse; 14.09.2012
comment
В Hibernate вы можете определить свой собственный диалект для сопоставления типов SQL с типами Java. Взгляните на интерфейс org.hibernate.dialect, но это не стандартный JPA. - person Omar Al Kababji; 17.09.2012
comment
FYI -: имя пользователя не работает с соединениями Oracle (docs.oracle.com/cd/E18283_01/java.112/e16548/) - person cs94njw; 09.04.2013
comment
@ cs94njw то, что вы прокомментировали, связано с драйвером Oracle JDBC, он не имеет ничего общего с именованными параметрами. - person Omar Al Kababji; 11.04.2013
comment
Важно, чтобы кто-то, читающий этот выпуск, знал, что драйвер Oracle не поддерживает именованные параметры. Я был бы признателен за это, если бы искал ответы. - person cs94njw; 12.04.2013
comment
Да, но вопрос связан с JPA / Hibernate, в этом случае именованные параметры поддерживаются даже при использовании Oracle. - person Omar Al Kababji; 12.04.2013
comment
Для собственных запросов использование именованных параметров не определено. stackoverflow.com/ questions / 3144235 / - person emeraldhieu; 20.11.2014
comment
Именованные параметры не работают для собственных запросов (пробовали с Postgresql), вместо них следует использовать позиционные параметры. - person P.Péter; 21.04.2015

Вот хранимая процедура DB2, которая получает параметр

SQL

CREATE PROCEDURE getStateByName (IN StateName VARCHAR(128))
DYNAMIC RESULT SETS 1
P1: BEGIN
    -- Declare cursor
    DECLARE State_Cursor CURSOR WITH RETURN for
    -- #######################################################################
    -- # Replace the SQL statement with your statement.
    -- # Note: Be sure to end statements with the terminator character (usually ';')
    -- #
    -- # The example SQL statement SELECT NAME FROM SYSIBM.SYSTABLES
    -- # returns all names from SYSIBM.SYSTABLES.
    -- ######################################################################
    SELECT * FROM COUNTRY.STATE
    WHERE PROVINCE_NAME LIKE UPPER(stateName);
    -- Cursor left open for client application
    OPEN Province_Cursor;
END P1

Ява

//Country is a db2 scheme

//Now here is a java Entity bean Method

public List<Province> getStateByName(String stateName) throws Exception {

    EntityManager em = this.em;
    List<State> states= null;
    try {
        Query query = em.createNativeQuery("call NGB.getStateByName(?1)", Province.class);
        query.setParameter(1, provinceName);
        states= (List<Province>) query.getResultList();
    } catch (Exception ex) {
        throw ex;
    }

    return states;
}
person Thakhani Tharage    schedule 07.06.2013

Предположим, ваш запрос: «выберите идентификатор, имя из пользователей, где rollNo = 1001».

Здесь запрос вернет объект с идентификатором и столбцом имени. Ваш класс Response выглядит следующим образом:

public class UserObject{
        int id;
        String name;
        String rollNo;

        public UserObject(Object[] columns) {
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getRollNo() {
            return rollNo;
        }

        public void setRollNo(String rollNo) {
            this.rollNo = rollNo;
        }
    }

здесь UserObject конструктор получит массив объектов и установит данные с помощью объекта.

public UserObject(Object[] columns) {
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        }

Ваша функция выполнения запроса похожа на приведенную ниже:

public UserObject getUserByRoll(EntityManager entityManager,String rollNo) {

        String queryStr = "select id,name from users where rollNo = ?1";
        try {
            Query query = entityManager.createNativeQuery(queryStr);
            query.setParameter(1, rollNo);

            return new UserObject((Object[]) query.getSingleResult());
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

Здесь вам нужно импортировать следующие пакеты:

import javax.persistence.Query;
import javax.persistence.EntityManager;

Теперь ваш основной класс, вы должны вызвать эту функцию. Сначала вам нужно получить EntityManager и вызвать эту getUserByRoll(EntityManager entityManager,String rollNo) функцию. Процедура вызова приведена ниже:

@PersistenceContext
private EntityManager entityManager;

UserObject userObject = getUserByRoll(entityManager,"1001");

Теперь у вас есть данные в этом userObject.

Вот импорт

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

Примечание.

query.getSingleResult () возвращает массив. Вы должны поддерживать положение столбца и тип данных.

select id,name from users where rollNo = ?1 

запрос возвращает массив, и это [0] --> id and [1] -> name.

Для получения дополнительной информации посетите этот ответ

Спасибо :)

person Md. Sajedul Karim    schedule 16.05.2018

JPA был разработан для обеспечения автоматического сопоставления между объектами и реляционной базой данных. Поскольку Integer не является постоянным объектом, зачем вам использовать JPA? Простой запрос JDBC подойдет.

person jmb    schedule 14.08.2017