2016-02-23 2 views
5

Ich verwende Spring Boot und Data Rest, um einen einfachen Microservice in Java8 zu erstellen und eine Postgres-Ausnahme zu erhalten.Spring Data Rest: Abfrage "Datum ist Null" löst eine Postgres-Ausnahme aus

Meine Einheit:

@Entity 
public class ArchivedInvoice implements Serializable { 
    ... 
    @Column 
    private String invoiceNumber; 
    @Column 
    private java.sql.Date invoiceDate; 
    ... 
} 

Meine Repository-Schnittstelle:

@RepositoryRestResource(collectionResourceRel = "archivedinvoices", path = "archivedinvoices") 
public interface ArchivedInvoiceRepository extends PagingAndSortingRepository < ArchivedInvoice, Long > { 
    ... 
@RestResource(rel = "findByXYZ", path = "findByXYZ") 
@Query(value = "SELECT ai FROM #{#entityName} ai WHERE " 
     + "(:invoiceNumber IS NULL OR ai.invoiceNumber LIKE :invoiceNumber) AND " 
     + "(:invoiceDate IS NULL OR ai.invoiceDate = :invoiceDate)" 
     ) 
public Page <ArchivedInvoice> findByXYZ(
     @Param("invoiceNumber") @Nullable String invoiceNumber, 
     @Param("invoiceDate") @Nullable Date invoiceDate, 
     Pageable p); 
    ... 
} 

Wenn ich „? .../findByXYZ invoiceDate = 2016.02.22" nennen, ich werde die folgende bekommen Fehlermeldung:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
... 
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
... 
Caused by: org.postgresql.util.PSQLException: FEHLER: could not determine data type of parameter 

Aber es funktioniert, wenn ich das entfernen: Teil "invoiceDate IS NULL". Wie kann ich überprüfen, ob der Parameter invoiceDate null ist?

+0

du http://stackoverflow.com/a/27193644/2055854 man versuchen könnte –

Antwort

0

Wenn Sie JPA mit Postgres verwenden, gibt es ein merkwürdiges Verhalten, das einen Fehler verursacht, wenn Sie überprüfen möchten, ob ein Parameter null ist, bevor Sie die gewünschte Bedingung später überprüfen.

Der Fehler tritt auf, weil JPA beim Lesen der Abfrage nicht identifizieren kann, was der Parametertyp ist, und dann einen Fehler beim Interpretieren der Abfrage auslösen.

Um dies zu umgehen, wechseln Sie die Positionen Ihrer Parameterbedingungen, um zuerst zu prüfen, ob die gewünschte Bedingung wahr ist, und dann zu prüfen, ob der Parameter null ist oder nicht.

Auf diese Weise kann JPA den korrekten Parametertyp identifizieren und der Fehler sollte nicht erneut ausgelöst werden.

Versuchen Sie, die folgende Abfrage und sehen, ob es funktionieren wird:

@Query(value = "SELECT ai FROM #{#entityName} ai WHERE " 
    + "(:invoiceNumber IS NULL OR ai.invoiceNumber LIKE :invoiceNumber) AND " 
    + "(ai.invoiceDate = :invoiceDate OR :invoiceDate IS NULL)" 
    ) 
+1

Leider ist dies tut nicht arbeiten. Aber es war eine großartige Idee! Danke! – user2722077

+0

Dies funktionierte für mich für den ersten Datumsparameter in der Abfrage und nicht für den Sendedatumsparameter. Ich habe zwei Datumsparameter in der Abfrage. Es beklagt sich für das zweite. –

2

Ich glaube @Bonifacio dass Postgres korrekt ist nicht in der Lage, die Art Ihres @Param("invoiceDate") Parameter zu bestimmen, wann der IS NULL Test durchführen. Ich habe ähnliche Abfragen wie Sie, die sich wie erwartet mit einer H2-Datenbank im Speicher verhalten, aber mit den Postgres-Integrationstests fehlschlagen.

ich war in der Lage, dies zu umgehen, indem Sie den Parameter auf einen Zeitpunkt Gießen etwa so:

@Query(value = "SELECT ai FROM #{#entityName} ai WHERE " 
    + "(:invoiceNumber IS NULL OR ai.invoiceNumber LIKE :invoiceNumber) AND " 
    + "(cast(:invoiceDate as date) IS NULL OR ai.invoiceDate = :invoiceDate)" 
    ) 
+0

Für andere Interessierte ist der Cast-Typ für UUID "binär" und nicht "anders" oder "varchar" – user1791139