【问题标题】:JPA query exceptionJPA 查询异常
【发布时间】:2026-02-12 03:00:01
【问题描述】:

我有一个使用EntityManager 构建的查询:

Query q = em
    .createQuery("SELECT * FROM :table WHERE username = :username AND password = MD5(:password)")
    .setParameter("table", User.class.getName())
    .setParameter("username", txtLogin.getText())
    .setParameter("password", passPassword.getPassword())
;

User user = (User) q.getSingleResult();

但我得到一个例外:

线程“AWT-EventQueue-0”中的异常 java.lang.IllegalArgumentException:一个 创建时发生异常 在 EntityManager 中查询:
例外 说明:解析语法错误 查询 [SELECT * FROM :table WHERE 用户名 = :用户名和密码 = MD5(:password)],第 1 行,第 7 列: 意外令牌 [*]。

如何解决?

查询中不能使用*吗?

【问题讨论】:

    标签: java mysql orm jpa jpql


    【解决方案1】:

    JPQL 语法与 SQL 不同,你可以这样做

    Select T from Thingy T
    

    而不是

    Select * from Thingy
    

    但这只是您问题的一部分。 SELECT t FROM :table t 也不起作用,因为 from 子句中不允许使用参数,而只能在 where 子句中使用。所以你必须这样做:

    Query q = em
        .createQuery("SELECT u FROM " + User.class.getName()
        + "u WHERE username = :username AND password = MD5(:password)")
        .setParameter("username", txtLogin.getText())
        .setParameter("password", passPassword.getPassword())
        ;
    

    此外,JPQL 中没有 MD5() 函数,因此要使用 MD5,您要么必须在 java 代码中执行此操作,要么使用本机 SQL 查询。

    【讨论】:

      【解决方案2】:

      是的,你不能这样使用*

      这是怎么做的。请注意,即使 SELECT 也是可选的

       Query q = em
          .createQuery("FROM " + User.class.getName() + " WHERE username = :username AND password = MD5(:password)")
          .setParameter("username", txtLogin.getText())
          .setParameter("password", passPassword.getPassword())
          ;
      
      User user = (User) q.getSingleResult();
      

      使用 SELECT 你可以这样做:

      Query q = em
          .createQuery("SELECT us FROM " + User.class.getName() + "us WHERE username = :username AND password = MD5(:password)")
          .setParameter("username", txtLogin.getText())
          .setParameter("password", passPassword.getPassword())
          ;
      

      【讨论】:

      • JPA 规范的哪一部分说“SELECT”是可选的?特别是,在 JPA2 规范的第 4.2.1 节中,我们有“select_statement :: = select_clause from_clause [where_clause] [groupby_clause] [have_clause] [orderby_clause]”“select_clause”根本不是可选的
      • 我不知道规格。但是,如果您想要select * from,则无需键入 SELECT。你可以只写FROM。也许是 hibernate 支持这一点,而不是专门的 jpa。