【问题标题】:use of entityManager.createNativeQuery(query,foo.class)使用 entityManager.createNativeQuery(query,foo.class)
【发布时间】:2011-01-07 19:45:34
【问题描述】:

我想从

返回一个整数列表

javax.persistence.EntityManager.createNativeQuery电话

为什么下面的不正确?

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

具体为什么我会得到“...未知实体:java.lang.Integer”

我是否必须创建一个具有单个字段的实体类,它是一个整数?

谢谢

【问题讨论】:

    标签: java jpa ejb-3.0


    【解决方案1】:

    您所做的称为投影。那时您只返回一个属于一个实体的 标量 值。您可以使用 JPA 执行此操作。见scalar value

    我认为在这种情况下,完全省略实体类型是可能的:

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

    示例取自here

    【讨论】:

    • 是的,我的疏忽我不需要第二个参数。仍然对为什么它不起作用感到困惑。我必须解决这个问题。谢谢
    • 最好使用命名参数而不是"?"
    【解决方案2】:

    这不起作用,因为第二个参数应该是一个映射实体,当然 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();
    

    问候。

    【讨论】:

    • 对于 JPA,有没有办法在使用本机查询时指定您希望如何转换标量值?我想在不循环和创建新整数的情况下使用List&lt;Integer&gt; values = q.getResultList();
    • 在 Hibernate 中,您可以定义自己的方言来将 SQL 类型映射到 Java 类型,看看 org.hibernate.dialect 接口,但这不是标准的 JPA。
    • 阅读此问题的人知道 Oracle 驱动程序不支持命名参数很重要。如果我正在寻找答案,我将不胜感激。
    • “命名参数的使用未定义为本机查询。” stackoverflow.com/questions/3144235/…
    • 命名参数不适用于本机查询(使用 Postgresql 尝试),您应该改用位置参数。
    【解决方案3】:

    这是一个接收参数的 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
    

    Java

    //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;
    }
    

    【讨论】:

      【解决方案4】:

      假设您的查询是“select id,name from users where rollNo = 1001”。

      这里查询将返回一个带有 id 和 name 列的对象。 您的 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] --&gt; id and [1] -&gt; name

      欲了解更多信息,请访问this Answer

      谢谢:)

      【讨论】:

        【解决方案5】:

        JPA 旨在提供对象和关系数据库之间的自动映射。由于 Integer 不是持久实体,为什么需要使用 JPA ?一个简单的 JDBC 请求就可以正常工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-09
          • 1970-01-01
          • 2011-09-22
          • 1970-01-01
          • 2019-06-04
          • 1970-01-01
          • 2020-12-23
          相关资源
          最近更新 更多