Java 带命名参数的本机查询因“未设置所有命名参数”而失败

Java 带命名参数的本机查询因“未设置所有命名参数”而失败,java,hibernate,jpa,Java,Hibernate,Jpa,我想执行一个简单的本机查询,但它不起作用: @Autowired private EntityManager em; Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username"); em.setProperty("username", "test"); (int) q.getSingleResult(); 为什么我会得到这个例外 org.hibernate.QueryExce

我想执行一个简单的本机查询,但它不起作用:

@Autowired
private EntityManager em;

Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username");
em.setProperty("username", "test");
(int) q.getSingleResult();
为什么我会得到这个例外

org.hibernate.QueryException: Not all named parameters have been set: [username]

使用查询中的set参数

Query q = (Query) em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");

JPA在本机查询中不支持命名参数,只支持JPQL。必须使用位置参数

命名参数遵循第4.4.1节中定义的标识符规则。命名参数的使用适用于Java持久性查询语言,而不是为本机查询定义的。只有位置参数绑定可移植地用于本机查询

所以,用这个

Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
虽然JPA规范不支持本机查询中的命名参数,但一些JPA实现(如)可能支持它

本机SQL查询支持位置参数和命名参数


但是,这会将您的应用程序与特定的JPA实现相结合,从而使其不可移植。

这是4.3.11版中修复的错误

编辑: 执行本机查询的最佳方法仍然是使用NamedParameterJdbcTemplate 它允许您检索非托管实体的结果;您可以使用行映射器,甚至可以使用命名参数的映射


经过多次尝试,我发现您应该使用createNativeQuery,并且可以使用replacement发送参数

以我为例


我用日食。此JPA允许本机查询采用以下方式:

Query q = em.createNativeQuery("SELECT * FROM mytable where username = ?username");
q.setParameter("username", "test");
q.getResultList();
您正在调用setProperty而不是setParameter。将代码更改为

Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username");
em.setParameter("username", "test");
(int) q.getSingleResult();

它应该可以工作。

不,这是正确的导入。但是您应该使用整数参数。NativeQuery不适用于字符串参数。我编辑了我的答案。顺便说一下,你可能想恢复编辑。它确实与命名参数一起工作。。。username=:username。通常,您应该获得命名参数username用于本机SQL查询,从username=:username的人员中选择count*。但本机SQL查询中不允许使用命名参数,请使用整数parameter@pL4Gu33Wihle JPA不支持这一点,有些实现支持,比如Hibernate。这就是为什么它适用于OP。我已经用这些信息编辑了我的答案。是的,但我忘记了…并在我的示例中测试它。请将此答案标记为正确。我知道这是一个旧线程,但JPA允许命名参数,原始问题的问题是:em.setPropertyusername,test;应该是这样的q.setParameterusername,test;提示一下,为什么要使用本机查询进行此查询?使用Jpa查询语言也可以做到这一点,使用Jpa查询有很多好处。@Rafael Zeffa我可以在没有@Entity类的情况下使用Jpa吗?如果是这样的话,您能建议如何使用jpa优化它吗?没有实体就无法优化它,但为什么不能为该表映射@实体呢?您可以调用setProperty。它应该是setParameter。另请参见查看此链接
Query q = em.createNativeQuery("SELECT * FROM mytable where username = ?username");
q.setParameter("username", "test");
q.getResultList();
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username");
em.setParameter("username", "test");
(int) q.getSingleResult();