【问题标题】:"org.hibernate.QueryException: Unable to resolve path..." error with parametrized queries on JPA“org.hibernate.QueryException:无法解析路径...” JPA 上的参数化查询错误
【发布时间】:2014-10-22 05:03:55
【问题描述】:

我对参数化 SQL 查询的以下方法的第一个参数有疑问:

lista = miDao.find("SELECT c FROM Idioma WHERE c.palabra =:param", o1 , entityManager);

地点:

String o1= "playa";
List<Object> lista;

表格“Idioma”有 3 列“palabra”、“idioma”和“wordId”。该方法预计会在“palabra”列中查找单词“playa”,并调用以下 Dao 方法:

@SuppressWarnings("unchecked")
public <T> List<T> find(String queryString, Object param, EntityManager em) {
    Query query = em.createQuery(queryString);
    query.setParameter( "param" , param);
    return query.getResultList();
}

当我运行程序时,我被“回滚”了:

Unable to resolve path [c.palabra], unexpected token [c] [SELECT c FROM com.aprendeidiomas.entity.Idioma WHERE c.palabra =:param]

我确定我的参数化 sql 查询有问题。即使我有很多文档,我也无法解决我的错误。你能告诉我我的参数化查询有什么问题吗?

非常感谢您。

【问题讨论】:

  • 什么是c?你的意思是SELECT c FROM Idioma c ...
  • "c" 是我要为“playa”替换的参数
  • 不,参数是param

标签: java mysql sql hibernate jpa


【解决方案1】:

首先,您使用的不是 SQL,而是 JPQL(或作为扩展的 HQL)。

接下来,错误消息已经告诉您出了什么问题:c 未知,因此无法解析c.palabra。我假设您的意思是选择与 param 中的单词匹配的所有成语,并且您的 Idioma 实体如下所示:

//Annotations and methods omitted for simplicity
class Idioma {
   String palabra; 
}

因此,您的查询应该指出 cIdioma 的别名,即
SELECT c FROM Idioma c WHERE c.palabra =:param

一个简短的分解:

  • SELECT c - 选择 c 的意思
  • FROM Idioma c - 选择 Idioma 实体并为其指定别名 c 以便查询知道返回匹配的实体
  • WHERE c.palabra = :param - 此条件意味着所有具有作为 param 传递的值(在您的示例中为 o1 的值)的实体都匹配它们的 palabra 属性。

澄清一下:在query.setParameter( "param" , param); 之后,查询internally 可能如下所示:

SELECT c FROM Idioma c WHERE c.palabra = "playa"


边注: 如果您想选择单词,请使用SELECT c.palabra ...

【讨论】:

  • 附注注释:您的意思是“SELECT c.palabra FROM Idioma c =:param”??
  • @VictorDoors no SELECT c.palabra FROM Idioma c WHERE c.palabra =:param
  • 非常感谢您的回答和您的耐心。现在一切都清楚了:)
  • 只是与此相关的最后一个问题。考虑到 palabra 是我的表 Idioma 的一列,检索我的表的所有“palabra”条目的命令是什么?我想知道这会是SELECT c.palabra FROM Idioma c WHERE c.palabra = ""
  • @VictorDoors 首先,对于 JPQL/HQL,您不应该考虑表和列,而应该考虑实体和属性。其次,您应该考虑WHERE c.palabra = "" 的含义:“返回属性palabra 为空字符串的所有实体”-> 显然不是您想要的。只需尝试不使用 where 子句即可获取 all 实体:SELECT c.palabra FROM Idioma c.
【解决方案2】:

我猜c应该是Idioma的实例? 所以你必须为你的声明者添加别名:

lista = miDao.find("SELECT c FROM Idioma c WHERE c.palabra =:param", o1 , entityManager);

【讨论】:

  • 感谢您的回复,但是添加别名是什么意思?注意:设置参数实例后的“c”应为“playa”。
  • 你描述c是什么类型的对象?请在您的问题中添加实体!
  • 你是对的!直到现在我才明白你添加别名的意思。 "c" 是 "Idioma" 的一个实例。
猜你喜欢
  • 2018-03-13
  • 2012-08-22
  • 2014-12-27
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 2014-02-24
  • 1970-01-01
相关资源
最近更新 更多