2014-10-30 57 views
0

我想将两个参数传递给namedquery。一个是数字类型,另一个是字符串类型。他们都可能是空的。例如,(id = null,username ='joe')和(id = 1,username ='joe')是两个不同的结果。在namedQuery中,如果id为null,则语法为“u.id is null”,但如果id不为null,则为“u.id =:id”。我的问题是如何动态处理namedQuery中的id字段?如何在JPA命名查询中处理数字类型的空值

请检查我的示例代码:

1.User.java

@NamedQueries({ 
     @NamedQuery(name = "getUser", query = "select u from User u" 
       + " where u.id = :id"  
       + " And u.username= :username") 
}) 
public class User{ 
    public Long id; 
    public String username; 
} 
  • UserDao.java
  • public User getUser(Long id, String username) { 
        TypedQuery<User> query = Dao.entityManager.createNamedQuery("getUser", User.class); 
        query.setParameter("id", id); 
        query.setParameter("username", username); 
    
        List<User> users = query.getResultList(); 
    
        if (users.size() > 0) { 
         return users.get(0); 
        } else { 
         return null; 
        } 
    } 
    

    = ======================================

    我曾尝试:

    1. 这是遗留代码,我不想改变结构。所以我不想使用Criteria。

    2. 从用户U其中选择U(:id为null或u.id =:ID)和u.username =:用户名

      //抛出异常:不一致的数据类型:预期数量有BINARY

    3. 从用户选择U U其中u.id = NULLIF(:ID,NULL)和u.username =:用户名

      //抛出异常:不一致的数据类型:预期数量有BINARY

    4. 我也尝试过nvl和解码namedQuery,不起作用。

    5. query.setParameter(“id”,id == null?-1:id)// did not work。

    我最后的选择是在UserDao文件中写入查询来替换用户文件中的namedQuery。

    谢谢!

    ===========================================

    我耗尽时间,不得不放弃使用namedQuery。我的解决办法:

    # UserDao.java 
    
        public User getUser(Long id, String usename) { 
         String getUser = "select u from user u where u.id " + Dao.isNull(id) 
             + " And u.username " + Dao.isNull(username); 
         Query query = Dao.entityManager.createQuery(getUser); 
        } 
    
    # Dao.java 
    
        public static String isNull(Object field) { 
         if (field != null) { 
           if (field instanceof String) { 
            return " = " + "'" + field + "'"; 
           } else { 
            return " = " + field; 
           } 
    
          } else { 
           return " is NULL "; 
          } 
        } 
    
    +0

    你确定问题出在参数上吗?除了这个空的问题,查询的工作原理和返回正确的结果? – 2014-10-30 15:44:58

    +0

    不是,oracle不会将空字符串视为空吗? – zmf 2014-10-30 15:45:37

    +0

    是的。这是空的问题。代码之前工作正常。我刚刚得到了这个问题,因为我们想改变id字段可能为空的要求。以前,id字段是非空的。 – Bryan 2014-10-30 15:49:07

    回答

    0

    如果)在查询的结尾是一个错误,尝试没有它

    @NamedQuery(name = "getUser", query = "select u from User u" 
          + " where (:id is null or u.id = :id)"  
          + " And :username" 
    

    编辑

    如果一切都失败了,这种快速的解决方法应该这样做(如果您没有数据库中的负号)与上述空检查结合使用

    query.setParameter("id", id == null ? -1 : id); 
    
    +0

    谢谢你你的改正。那是我的错字。该方法不起作用。 – Bryan 2014-10-30 15:34:09

    +0

    这是一个查询,而不是一个java语句。 ':id is null'在查询世界中没有意义,因为':id'是数据库未知的变量。 – pms 2014-10-30 15:34:41

    +0

    @pmp它不是毫无意义的,它故意使用变量。像这样的表达式的意思是,如果你传递'null'作为参数值,'OR'的左侧将被评估为'true',所以右侧将不被考虑。 – 2014-10-30 15:39:17

    3

    您不能在运行时更改命名查询。这样做会破坏指定查询的目的。 动态查询应该使用标准api创建。

    请参阅this回答在指定查询中使用什么。

    from CountryDTO c where 
        ((:status is null and c.status is null) or c.status = :status) 
        and c.type =:type 
    
    +0

    试过。抛出异常:ORA-00932:不一致的数据类型:期望的NUMBER得到BINARY – Bryan 2014-10-30 15:31:27