Hibernate假设HQL查询中的参数没有

时间:2011-06-16 08:34:03

标签: hibernate hql

为什么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]

2 个答案:

答案 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。你的配置是什么? -