@Formula注解SQL表达式首尾括号的作用及报错原因
@Formula注解表达式首尾括号的作用 Hibernate的@Formula注解不会对配置的表达式内容做任何语法补全或适配,会将字符串原样拼接进最终生成的SELECT查询的字段列表中,手动添加的首尾括号,本质是为了满足SQL语法对SELECT子句中标量子查询的格式要求。
不加括号触发语法错误的逻辑
如果不在子查询外加括号,Hibernate拼接完成的SQL会出现结构错误,大致形态如下:
select company0_.id, company0_.company_name, select count(c.id) from Contact c where c.company_id = company0_.id as contactCount from Company company0_
按照SQL标准,出现在SELECT字段位置、返回单个值的标量子查询,必须用圆括号包裹。上面的语句直接把select开头的子查询裸放在字段列表里,MySQL解析器会把这个select识别为主查询的关键字,无法判定这是一个计算字段的子逻辑,直接抛出语法错误。
加括号后正常运行的原因
给子查询加上首尾括号后,拼接出的SQL完全符合语法规范:
select company0_.id, company0_.company_name, (select count(c.id) from Contact c where c.company_id = company0_.id) as contactCount from Company company0_
此时SQL解析器可以明确识别括号包裹的内容是一个独立的标量子查询,会单独执行子查询计算结果,将其作为contactCount字段的值返回,整个查询就能正常运行。
使用提示
- 只有
@Formula中写独立子查询的时候需要手动加首尾括号,如果是普通字段运算逻辑,比如计算折后价price * discount、拼接姓名concat(first_name, last_name)这类不需要单独查表的表达式,不需要额外加括号,直接写入即可正常运行。 @Formula中写入的是原生SQL,Hibernate不会根据数据库方言做自动转换,写表达式时需要匹配你当前使用的数据库语法。
内容的提问来源于stack exchange,提问作者user7514788
相关产品推荐
相关产品推荐

