如何强制Hibernate为生成的SQL语句添加引号?
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在角色中定义。
谢谢!
爱德华
更改您的ID为Long
类类型,而不是原始的。然后Hibernate将简单地生成查询为ROLE_ID = 2,这是100%有效的,因为数字不需要刻度或引号。
这就是诀窍!谢谢! – 2010-10-30 18:17:58
@Eduardo:很高兴你解决了它。我也喜欢你阅读这个答案,它的相关性有点。 – 2010-11-02 08:52:06
的Hibernate属性hibernate.globally_quoted_identifiers =真会做的伎俩
我不认为蜱或报价是你的问题就在这里。你为什么使用bigint(20)来存储ID?你可以发布你的映射或注释实体吗? – hisdrewness 2010-10-29 04:02:20
@hisdrewness:当然,我已将注释类部分添加到帖子中。谢谢您的回复! – 2010-10-29 04:35:25
看起来你可以将你的id改为“Long”类而不是原始类。然后Hibernate将简单地生成查询为ROLE_ID = 2,这是100%有效的,因为数字不需要刻度或引号。 – hisdrewness 2010-10-29 14:26:40