Java 带空参数的Spring数据jpa本机查询(PostgreSQL)
问题是如何使本机查询接受空参数 我的问题是:Java 带空参数的Spring数据jpa本机查询(PostgreSQL),java,spring,postgresql,hibernate,spring-data-jpa,Java,Spring,Postgresql,Hibernate,Spring Data Jpa,问题是如何使本机查询接受空参数 我的问题是: @Query(value = "SELECT " + " summaries.event_type as \"eventType\", " + " summaries.institution_id as \"institutionId\", " + "
@Query(value = "SELECT " +
" summaries.event_type as \"eventType\", " +
" summaries.institution_id as \"institutionId\", " +
" identifiers.id as \"studentIdentifierId\", " +
" identifiers.name as \"studentIdentifierName\" " +
"FROM summaries " +
"LEFT JOIN roles ON summaries.student_id=roles.id " +
"LEFT JOIN identifiers ON roles.identifier_id=identifiers.id " +
"WHERE " +
" summaries.student_id IS NOT NULL AND " +
" summaries.event_type IN (:eventTypes) AND " +
" (:identifierId IS NULL OR roles.identifier_id=:identifierId) " +
"GROUP BY " +
" summaries.institution_id, " +
" summaries.student_id, " +
" identifiers.id, " +
" identifiers.name, " +
" summaries.event_type",
nativeQuery = true)
List<CustomProjection> findByCustomCondition(
@Param("identifierId") Long identifierId,
@Param("eventTypes") List<String> eventTypes);
这似乎是因为行(:identifierId为NULL或roles.identifier\u id=:identifierId)
在这里引起了一个问题,但实际上找不到一个好的解决方案,因为据我所知它应该正常工作(当我在pgAdmin上直接使用此查询时,它应该正常工作,所以我很确定这是一个与映射相关的问题)
我试图转换标识符(cast(:identifierId为bigint)
),但没有帮助
另外,这是一个遗留项目,所以我使用以下版本:
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.6.RELEASE'
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.2'
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.17.Final'
这是Hibernate+PostgreSQL的一个常见问题,解决方案是自己实现该方法,而不是让Spring为您实现。在实现中,您必须这样做
List<CustomProjection> findByCustomCondition(
@Param("identifierId") Long identifierId,
@Param("eventTypes") List<String> eventTypes) {
// entityManager is acquired with the @PersistenceContext annotation as an injectable
Query q = entityManager.createNativeQuery(..., CustomProjection.class);
// the important part:
q.setParameter("identifierId", 0L);
q.setParameter("identifierId", identifierId);
...
List findByCustomCondition(
@参数(“标识符”)长标识符,
@参数(“事件类型”)列表(事件类型){
//entityManager是以@PersistenceContext注释作为可注入对象获取的
Query q=entityManager.createNativeQuery(…,CustomProjection.class);
//重要的部分是:
q、 设置参数(“标识ID”,0L);
q、 setParameter(“identifierId”,identifierId);
...
第一次调用
setParameter
确保Hibenate使用正确的类型设置器,第二次调用在没有执行查询的情况下覆盖第一个值,并跳过类型检测。通过在角色之间添加空格来修改查询。标识符id=:identifierId
应该类似于角色。标识符id=:identifierId
Yo您将不得不使用以下内容:(强制转换(:identifierId为bigint)为NULL或roles.identifier\u id=:identifierId)
正如@coladict的回答中所提到的,很遗憾,您无法使用clean Spring Data JPA解决方案实现您想要的功能。因此,您可以使用EntityManager
和hibernate特有的setParameter
重写查询,该选项允许显式指定绑定参数类型:
import org.hibernate.type.LongType;
// ...
List results=entityManager.createNamedQuery(“按自定义条件查找”)
.unwrap(org.hibernate.query.query.class)
.setParameter(“identifierId”,identifierId,LongType.INSTANCE)
.getResultList();
然后,您可以将@namednaviquery
与@SqlResultSetMapping
一起使用,将本机查询结果映射到自定义投影
。请参阅hibernate中的示例
另请参阅关于JPA和Hibernate查询中的
setParameter
用法。您使用什么类型的角色。标识符id
?我使用bigint
错误似乎与提取结果集有关,自定义投影的字段是什么?String-eventType,Long-institutionId,Long-studentIdentifierId,String-studentIdentifierName。当我将identifierId传递为例如0L
时,它不会中断,因此我不确定它是否与投影相关。
List<CustomProjection> findByCustomCondition(
@Param("identifierId") Long identifierId,
@Param("eventTypes") List<String> eventTypes) {
// entityManager is acquired with the @PersistenceContext annotation as an injectable
Query q = entityManager.createNativeQuery(..., CustomProjection.class);
// the important part:
q.setParameter("identifierId", 0L);
q.setParameter("identifierId", identifierId);
...