2010-10-29 60 views
2

Hibernate正在爲特定的條件查詢生成無效的SQL。我可以通過向WHERE子句中使用的值添​​加單引號來手動修復查詢。如何強制Hibernate爲生成的SQL語句添加引號?

where (role0_.ROLE_ID=2L) 

到:

爲了解決這個問題,我從改變查詢

where (role0_.ROLE_ID=`2L`) 

如何強制休眠添加單引號(在MySQL中是單引號,但在其他數據庫系統它可能是其他的東西)來包含在生成的SQL查詢中使用的

完整生成的查詢是:

select permission1_.PERMISSION_ID as PERMISSION1_12_, 
    permission1_.IS_REQUIRED as IS2_12_, 
    permission1_.SOURCE_ROLE_ID as SOURCE3_12_, 
    permission1_.TARGET_ROLE_ID as TARGET4_12_ 
from (
     select ROLE_ID, 
     NAME, 
     DESCRIPTION, 
     IS_ACTION, 
     LABEL, 
     null as FIRST_NAME, 
     null as LAST_NAME, 
     null as PASSWORD_HASH, 
     1 as clazz_ from GROUPS 
    union 
     select ROLE_ID, 
      NAME, 
      null as DESCRIPTION, 
      null as IS_ACTION, 
      null as LABEL, 
      FIRST_NAME, 
      LAST_NAME, 
      PASSWORD_HASH, 
      2 as clazz_ from USERS 
    ) 
role0_ inner join PERMISSIONS permission1_ on role0_.ROLE_ID=permission1_.SOURCE_ROLE_ID 
    where (role0_.ROLE_ID=2L) 

基本上我想由Hibernate加入這個單引號。

生成此查詢的條件查詢:

EntityManager entityManager = getEntityManager(); 
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery(); 

Class<?> queryScopeClass = temp.pack.commons.user.Role.class; 
Root<?> from = criteriaQuery.from(queryScopeClass); 

Path<?> idAttrPath = from.get("id"); 
// also tried criteriaBuilder.equal(idAttrPath, new Long(2)) 
Predicate predicate = criteriaBuilder.equal(idAttrPath, criteriaBuilder.literal(new Long(2))) 
criteriaQuery.where(predicate); 

Path<?> attributePath = from.get("permissions"); 
PluralAttributePath<?> pluralAttrPath = (PluralAttributePath<?>)attributePath; 
PluralAttribute<?, ?, ?> pluralAttr = pluralAttrPath.getAttribute(); 

Join<?, ?> join = from.join((SetAttribute<Object,?>)pluralAttr); 

TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery.select(join)); 
return (List<P>)typedQuery.getResultList(); 

請讓我知道如果你有關於如何強制Hibernate的單引號添加至值(而不是列/表名)的任何線索。

在我的實體角色中,出現在WHERE子句中的id屬性當然是long類型的。

追問:類型在數據庫中的id列的是bingint:

+---------------+--------------+------+-----+---------+-------+ 
| Field   | Type   | Null | Key | Default | Extra | 
+---------------+--------------+------+-----+---------+-------+ 
| ROLE_ID  | bigint(20) | NO | PRI | NULL |  | 

... 

這是怎樣的角色類已經被註釋:

@Entity(name="Role") 
@Table(name = "ROLES") 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
@javax.persistence.TableGenerator(
    name="GENERATED_IDS", 
    table="GENERATED_IDS", 
    valueColumnName = "ID" 
) 
public abstract class Role implements Serializable { 
    private static final long serialVersionUID = 1L; 


    /** 
    * The id of this role. Internal use only. 
    * 
    * @since 1.0 
    */ 
    @Id @GeneratedValue(strategy = GenerationType.TABLE, generator="GENERATED_IDS") 
    @Column(name = "ROLE_ID") 
    protected long id; 


    /** 
    * Set of permissions granted to this role. 
    * 
    * @since 1.0 
    */ 
    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy="sourceRole") 
    protected Set<Permission> permissions = new HashSet<Permission>(); 

... 

} 

我用每類表繼承策略,這就是爲什麼您在用戶和組實體的生成查詢中看到聯合的原因。他們擴展角色。 Id在角色中定義。

謝謝!

愛德華

+0

我不認爲蜱或報價是你的問題就在這裏。你爲什麼使用bigint(20)來存儲ID?你可以發佈你的映射或註釋實體嗎? – hisdrewness 2010-10-29 04:02:20

+0

@hisdrewness:當然,我已將註釋類部分添加到帖子中。謝謝您的回覆! – 2010-10-29 04:35:25

+0

看起來你可以將你的id改爲「Long」類而不是原始類。然後Hibernate將簡單地生成查詢爲ROLE_ID = 2,這是100%有效的,因爲數字不需要刻度或引號。 – hisdrewness 2010-10-29 14:26:40

回答

1

更改您的ID爲Long類類型,而不是原始的。然後Hibernate將簡單地生成查詢爲ROLE_ID = 2,這是100%有效的,因爲數字不需要刻度或引號。

+0

這就是訣竅!謝謝! – 2010-10-30 18:17:58

+0

@Eduardo:很高興你解決了它。我也喜歡你閱讀這個答案,它的相關性有點。 – 2010-11-02 08:52:06

4

的Hibernate屬性hibernate.globally_quoted_identifiers =真會做的伎倆