![](/img/trans.png)
[英]Spring Boot JPA Native Query - is not null check based on parameter
[英]Spring data jpa native query with null parameter (PostgreSQL)
問題是如何讓我的本機查詢接受 null 參數?
這是我的查詢:
@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)
),但它沒有幫助。
PS。 這是一個遺留項目,所以這些是我使用的版本:
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 使用正確的類型設置器,第二次調用在沒有執行查詢的情況下覆蓋第一個值,並跳過類型檢測。
通過在roles.identifier_id=:identifierId
之間添加空格來修改查詢應該像roles.identifier_id= :identifierId
您將不得不使用以下內容: (cast(:identifierId as bigint) IS NULL OR roles.identifier_id=:identifierId)
正如@coladict 的回答中提到的那樣,不幸的是,您無法使用干凈的 Spring Data JPA 解決方案來做到這一點。 因此,您可以使用EntityManager
和休眠特定的setParameter
重寫您的查詢,該setParameter
允許顯式指定綁定參數類型:
import org.hibernate.type.LongType;
// ...
List<CustomProjection> results = entityManager.createNamedQuery("find_by_custom_condition" )
.unwrap(org.hibernate.query.Query.class)
.setParameter("identifierId", identifierId, LongType.INSTANCE)
.getResultList();
然后你可以使用@NamedNativeQuery
與@SqlResultSetMapping
映射本地查詢結果的CustomProjection
。 請參閱休眠文檔中的示例。
另請參閱有關在 JPA 和 Hibernate 查詢中使用setParameter
文章。
所以這不是上述問題的確切答案,但我遇到了類似的問題,我想我會在這里添加它,對於那些遇到這個問題的人。
我正在使用本機查詢,其中查詢的 in 子句可能為空,即:
WHERE (cm.first_name in (:firstNames) OR :firstNames is NULL)
我收到了bytea
錯誤,最后我能夠發送一個空列表。
(null == entity.getFirstName()? Collections.emptyList() : entity.getFirstName())
在這種情況下,將空列表發送到解析器起作用,而 null 則不起作用。
希望這可以為遇到此問題的人節省一些時間,以尋找如何將 null 傳遞給本機查詢的列表參數。
當 booleanParameterValue 為 null 時,以下代碼也適用於我。 我的數據庫是 Oracle,應用程序使用 jpql 和 hibernate。
Query query = getEntityManager().createNamedQuery("findBankAccountInfos");
query.setParameter("booleanParameter", Boolean.FALSE);
query.setParameter("booleanParameter", booleanParameterValue);
否則應用程序將引發以下異常:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected BINARY got NUMBER
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.