【发布时间】:2014-12-26 17:00:31
【问题描述】:
我想将两个参数传递给命名查询。一种是数字类型,另一种是字符串类型。它们都可以为空。
例如,(id=null, username='joe') 和 (id=1, username='joe') 是两个不同的结果。在 namedQuery 中,如果 id 为 null,则语法为“u.id is null”,如果 id 不为 null,则语法为“u.id = :id”。我的问题是如何动态处理namedQuery中归档的id?
请查看我的示例代码:
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;
}
}
========================================
我尝试过的:
这是遗留代码,我不想更改结构。所以我不想使用 Criteria。
-
从用户 u 中选择 u,其中 (:id 为 null 或 u.id= :id) 和 u.username= :username
// 抛出异常:不一致的数据类型:预期的 NUMBER 得到了 BINARY
-
从用户 u 中选择 u 其中 u.id= nullif(:id, null) 和 u.username= :username
// 抛出异常:不一致的数据类型:预期的 NUMBER 得到了 BINARY
我也试过nvl和namedQuery中的decode,没用。
query.setParameter("id", id==null?-1:id) // 没用。
我最后的选择是在 UserDao 文件中编写查询来替换 User 文件中的 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 ";
}
}
【问题讨论】:
-
您确定问题出在参数上吗?除了这个 null 问题之外,查询还能正常工作并返回正确的结果?
-
oracle 不将空字符串视为 Null 吗?
-
是的。这是空问题。该代码之前运行良好。我刚刚遇到了这个问题,因为我们想更改 id 字段可以为空的要求。以前,id 字段是非空的。
-
那个 id 字段是主键吗?为什么需要一个接受空值的主键字段?对我来说听起来不对!
-
如果它是唯一的主键,那么该查询的第二部分就无关紧要了。
标签: java jpa named-query