为什么Hibernate会抱怨以下查询:
public Set<Long> findImageVariantIdsWithOutOfBoundsDimension() {
final StringBuilder queryBuilder = new StringBuilder();
queryBuilder.append("select id from ImageVariant where ");
// imageVariantType is something like R_110X75 with 110 being max x.
// cast(substring( extracts 110.
queryBuilder.append("dimensionX > cast(substring(imageVariantType, 3, locate('X', imageVariantType) - 3), int) ");
queryBuilder.append("or ");
// imageVariantType is something like R_110X75 with 75 being max y.
// cast(substring( extracts 75.
queryBuilder.append("dimensionY > cast(substring(imageVariantType, locate('X', imageVariantType) + 1), int)");
final Query query = getEntityManager().createQuery(queryBuilder.toString());
@SuppressWarnings("unchecked")
final Set<Long> result = new HashSet<Long>(query.getResultList());
return result;
}
警告为Function template anticipated 3 arguments, but 2 arguments encountered
。但是,我的查询既不包含标记也不包含参数。由于cast
是一个特定于Hibernate的函数(在JPQL中没有字符串到int的转换),我认为这是一个HQL问题。
当我调试Hibernate的TemplateRenderer
时,我发现它的内部参数列表是['X', imagevaria0_.imagevarianttype]
。
答案 0 :(得分:3)
这基本上是Hibernate警告,没有调用某些SQL函数及其所有可允许的参数。在您的情况下,这是LOCATE
函数。此函数的语法为LOCATE(string1, string 2, [start])
,其中start
是一个可选参数,用于指定从哪里开始搜索的第一个字符的索引。
在您的情况下,您将此函数称为locate('X', imageVariantType)
,仅传递两个参数而不是最多允许的3个参数。 Hibernate类TemplateRenderer
检测到这一点并生成您看到的警告消息。
我已经与Hibernate团队一起提出bug来降低此消息的严重性(因为它在大多数情况下不会阻止查询正常工作)或者更好地检查它以便警告在对给定SQL函数有效的情况下不会生成。
对于遇到类似问题的任何人,如果查询工作正常,可以简单地忽略此警告。
答案 1 :(得分:1)
当您知道它是hibernate特定功能时,为什么要使用JPA创建查询?
尝试获取hibernate会话并在其上创建查询。您可以使用
进行休眠会话Session session = (Session) em.getDelegate();
编辑:getEntityManager()。createQuery(queryBuilder.toString()); 假设您传递的查询字符串是JPQL吗?您不应该在此使用HQL特定功能。 您需要获取HQL会话而不是JPA实体管理器来创建查询。
编辑:我试过这个,它对我来说很好。我的配置是带有Hibernate 3.6.0和MySQL 5.1.28的JPA 2.0。你的配置是什么? -