2016-04-28 43 views
1

我嘗試爲名稱爲User的類建立findAll查詢。使用休眠的SessionFactory它工作正常,但與休眠的EntityManager我得到一個錯誤。JPA查詢名稱爲Hibernate的用戶表

的原因似乎是escaping(用方括號[])的MS SQL Server的關鍵字user的,但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(); 
    } 
} 

研究:

這些解決方案都不能正常工作了。有沒有辦法在Hibernate的JPA查詢中使用表名[user]

回答

0

我發現基於JPA 2規範的解決方案(https://stackoverflow.com/a/3217488/5277820)與@Table

2.13數據庫對象的命名

[...]

要指定分隔標識符,下列方法之一,必須使用:

  • ,能夠指定在使用持久性單元的所有數據庫的標識符被處理作爲 通過在對象/關係xml映射文件的 persistence-unit-defaults元素中指定<delimited-identifiers/>元素來定界標識符。如果指定了 <delimited-identifiers/>元素,則它不能被覆蓋。

  • 它可以指定在每個名稱的基礎,對於一個數據庫對象的名稱將被解釋 爲分隔標識符如下:

    • 使用註釋,名稱被指定爲一個通過將名稱 包含在雙引號內來區分標識符,從而內部引號可以被轉義,例如, @Table(name="\"customer\"")
    • 當使用XML,一個名稱被指定爲通過使用雙 引號的分隔標識符,例如,<table name="&quot;customer&quot;"/>

代碼:

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

請試試這個,而不是

@Entity(name = "'user'") 

@Entity("\"user\"") 
1

表名(@Table)是數據庫中表的名稱。名稱中允許使用的字符取決於數據庫(SQL Server,Oracle,MySQL等)。

實體名稱(@Entity)由JPA和Hibernate用於引用實體。該名稱必須符合Java標識符允許的字符,因此它不能包含[]。當Hibernate嘗試將HQL查詢翻譯成SQL時,解析器會因爲意外的令牌錯誤而失敗,因爲它不支持實體名稱中的[]

Java EE 6 Tutorial解釋實體名稱中允許或不允許的內容。

因爲EntityManager方法不會失敗,這是因爲在調用EntityManager方法時,Hibernate不使用常規HQL查詢。 Hibernate啓動時會生成persist和find的SQL,因此HQL解析器不會用於這些操作。我想缺少一個驗證,Hibernate在啓動時應該給出一個錯誤,如果實體在特定情況下無效,而不是在運行時失敗。