JPA Criteria Like查询:如何阻止NVARCHAR字段转为Varchar(255)?
问题描述
我用JPA Criteria对NVARCHAR类型的events字段(最大可存储2000字符)执行Like查询,当前代码如下:
if (Objects.nonNull(eventStatus)) { String eStat = "\"event_status\""; String val = "\""+eventStatus+"\""; predicates.add(cb.like(item.get("events").as(String.class), "%"+eStat+"%"+" "+val+"%")); }
但查询未得到预期结果,查看SQL日志发现生成的语句中存在:
Hibernate: select count(itemadditi0_.item_additional_info_id) as col_0_0_ from Allocation.item_additional_info itemadditi0_ where itemadditi0_.tenant_id=? and ( cast(itemadditi0_.events as varchar(255)) like ? )
推测问题出在cast(itemadditi0_.events as varchar(255)) like ?这一行——直接在SSMS中执行以下查询可正常得到结果:
select item_nbr,item_status,events from Allocation.item_additional_info where events like '%"event_status"%"Past"%';
实体类中events字段的定义如下:
@Column(name="events",columnDefinition="nvarchar") @Convert(converter = EventConverterJson.class) private List<EventInfo> events;
请问如何解决该问题,或如何阻止JPA Criteria执行该类型转换?
解决方案
1. 修正字段的Column定义,指定完整长度
当前@Column的columnDefinition仅写了nvarchar,未指定长度,Hibernate默认会按varchar(255)处理类型转换。改成指定长度为2000,让Hibernate匹配字段实际存储长度:
@Column(name="events",columnDefinition="nvarchar(2000)") @Convert(converter = EventConverterJson.class) private List<EventInfo> events;
这样生成的Cast语句会使用nvarchar(2000),不会截断原字段内容。
2. 调整Criteria查询逻辑,避免强制转换截断
因为events字段通过@Convert转成JSON字符串存储,本质是字符串类型,直接使用cb.like时,可通过指定CAST函数的目标类型长度来规避自动截断:
if (Objects.nonNull(eventStatus)) { String pattern = "%\"event_status\"%\""+eventStatus+"\"%"; // 手动指定CAST到nvarchar(2000),覆盖Hibernate的默认短长度转换 predicates.add(cb.like( cb.function("CAST", String.class, item.get("events"), cb.literal("nvarchar(2000)")), pattern )); }
3. 改用原生SQL查询绕开Criteria自动转换
如果上述方法仍无法解决,直接使用原生SQL查询绕过JPA Criteria的自动类型转换逻辑:
String sql = "SELECT COUNT(item_additional_info_id) FROM Allocation.item_additional_info WHERE tenant_id = ? AND events LIKE ?"; Query query = entityManager.createNativeQuery(sql); query.setParameter(1, tenantId); query.setParameter(2, "%\"event_status\"%\""+eventStatus+"\"%"); Long count = (Long) query.getSingleResult();
内容的提问来源于stack exchange,提问作者SUVAM ROY
相关产品推荐
相关产品推荐

