首页 > 解决方案 > Hibernate 规范不使用参数 sql server

问题描述

我编写了一个在JpaSpecificationExecutor查询中使用的自定义谓词。为该查询生成的 SQL 不使用参数,因此查询缓存有 2 个条目(因为查询相差 1 个字符!)。聚合函数的使用是导致我看到的差异的原因吗?(下面列出)。

我的应用程序使用 sqlserver 2012 作为其数据库,并且我通过 sqlserver management studio 监控了查询。我观察到使用参数 for billingTypeand recordedDatebut not的输出recordedValue

以下是我使用的谓词代码:

Subquery<Entity> subQuery = query.subquery(Entity.class);
Root<Entity> subQueryRoot = subQuery.from(Entity.class);
subQuery.select(subQueryRoot.get("userId"));

Optional<Predicate> teamEquals = // Call to helper

Predicate isMinutes = builder.equal(subQueryRoot.get("billingType"), BillingType.MINUTES);
Predicate minutesDate = builder.greaterThan(subQueryRoot.get("recordedDate"), LocalDate.now().minus(Period.parse(params.getHoursPeriod())));
Predicate minutesThreshold = builder.greaterThan( subQueryRoot.get("recordedValue"), params.getHours() * 60 );
Predicate minutesRestriction = builder.and(isMinutes, minutesDate, minutesThreshold);

Predicate isDocuments = builder.equal(subQueryRoot.get("billingType"), BillingType.DOCUMENTS);
Predicate documentsDate = builder.greaterThan(subQueryRoot.get("recordedDate"), LocalDate.now().minus(Period.parse(params.getDocumentsPeriod())));
Predicate documentsThreshold = builder.greaterThan( subQueryRoot.get("recordedValue"), params.getDocuments() );
Predicate documentsRestriction = builder.and(isDocuments, documentsDate, documentsThreshold);

subQuery.where( builder.and(teamEquals.get(), builder.or( minutesRestriction, documentsRestriction ) ) );
return Optional.of(subQuery);

这导致 2 个生成的查询相差 1 个字符。例如(在 HQL 中) SELECT * FROM User where id IN (SELECT userId FROM Entity WHERE billingType = @p1 AND recordedDate > @p2 AND recordedValue > 0) 与。 SELECT * FROM User where id IN (SELECT userId FROM Entity WHERE billingType = @p1 AND recordedDate > @p2 AND recordedValue > 40)

标签: javaspringhibernate

解决方案


这听起来像是以下 Hibernate 错误https://hibernate.atlassian.net/browse/HHH-9576

在Why Hibernate inlines Integer parameter list passing to JPA Criteria Query中似乎也记录了一种解决方法?


推荐阅读