簡體   English   中英

Spring 數據 jpa 本機查詢與 null 參數 (PostgreSQL)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM