【问题标题】:JPA query for table with name user with Hibernate使用 Hibernate 对名称为 user 的表进行 JPA 查询
【发布时间】:2016-04-28 13:22:32
【问题描述】:

我尝试为名称为 User 的类构建一个 findAll 查询。使用 Hibernate 的 SessionFactory 它工作正常,但使用 Hibernate 的 EntityManager 我得到一个错误。

原因似乎是MS SQL Server关键字userescaping(带括号[]),但是用EntityManager#persist(Object)EntityManager#find(Class, Object)我没有问题。

堆栈跟踪:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: [ near line 1, column 29 [select generatedAlias0 from [user] as generatedAlias0]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:91)
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:109)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:304)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:203)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:568)
    ... 103 more

代码:

@Entity(name = "[user]")
public class User {
    // some properties
}

public class UserDao

    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findAll() {
        CriteriaQuery<User> criteriaQuery = entityManager.getCriteriaBuilder().createQuery(User.class);
        Root<User> root = criteriaQuery.from(User.class);
        criteriaQuery.select(root);
        return entityManager.createQuery(criteriaQuery).getResultList();
    }
}

研究:

这些解决方案也不起作用。有什么方法可以在 JPA 查询中使用表名 [user] Hibernate?

【问题讨论】:

    标签: java sql-server hibernate jpa


    【解决方案1】:

    表名(@Table)是数据库中表的名称。名称中允许的字符取决于数据库(SQL Server、Oracle、MySQL 等)。

    JPA 和 Hibernate 使用实体名称 (@Entity) 来引用实体。名称必须符合 Java 标识符允许的字符,因此不能包含 []。当 Hibernate 尝试将 HQL 查询转换为 SQL 时,解析器失败并出现意外的令牌错误,因为它不支持实体名称中的 []

    Java EE 6 Tutorial 解释了实体名称中允许或不允许的内容。

    对于 EntityManager 方法它不会失败的原因是,当调用 EntityManager 方法时,Hibernate 不使用常规的 HQL 查询。用于持久化和查找的 SQL 是在启动 Hibernate 时生成的,因此这些操作不使用 HQL 解析器。我想缺少验证,如果实体无效,Hibernate 应该在启动时给出错误,而不是在特定情况下在运行时失败。

    【讨论】:

      【解决方案2】:

      我找到了一个基于 JPA 2 规范的解决方案 (https://stackoverflow.com/a/3217488/5277820) 和 @Table

      2.13 数据库对象的命名

      [...]

      要指定分隔标识符,必须使用以下方法之一:

      • 可以指定将所有用于持久性单元的数据库标识符视为 通过在 persistence-unit-defaults 对象/关系 xml 映射文件的元素。如果 &lt;delimited-identifiers/&gt; 元素已指定,不能被覆盖。

      • 可以基于每个名称指定要解释的数据库对象的名称 作为分隔标识符如下:

        • 使用注释,通过将名称括起来将名称指定为分隔标识符 在双引号内,内部引号被转义,例如, @Table(name="\"customer\"")
        • 使用 XML 时,名称通过使用 double 指定为分隔标识符 引号,例如,&lt;table name="&amp;quot;customer&amp;quot;"/&gt;

      代码:

      @Entity
      @Table(name = "[user]")
      public class User {
          // some properties
      }
      

      【讨论】:

        【解决方案3】:

        请试试这个

        @Entity(name = "'user'")
        

        @Entity("\"user\"")
        

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 2022-07-11
          • 2021-03-07
          • 1970-01-01
          • 2021-09-24
          • 1970-01-01
          • 1970-01-01
          • 2018-11-16
          • 2012-02-14
          相关资源
          最近更新 更多