问题是如何让我的原生查询接受空参数?
这是我的查询:
@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 传递时,我收到错误消息:
InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet.
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = bytea
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
(:identifierId IS NULL OR roles.identifier_id=:identifierId)
行似乎在这里引起了问题,但无法真正找到好的解决方案,因为据我了解它应该有效通常(当我直接在 pgAdmin 上使用此查询时,它会正常工作,所以我很确定这是与映射相关的问题)。
我尝试转换标识符 (cast(:identifierId as 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);
...
第一次调用 setParameter
确保 Hibenate 使用正确的类型 setter ,第二次调用覆盖第一个值而不执行查询,并跳过类型检测。
关于java - 带有空参数的 Spring 数据 jpa native 查询(PostgreSQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64992940/