2015-05-22 18 views
17

Ich verwende Spring Data JPA (mit Hibernate als meine JPA-Provider) und will eine exists Methode mit einer HQL-Abfrage definieren angehängt:Spring Data JPA und Exists Abfrage

public interface MyEntityRepository extends CrudRepository<MyEntity, String> { 

    @Query("select count(e) from MyEntity e where ...") 
    public boolean existsIfBlaBla(@Param("id") String id); 

} 

Wenn ich diese Abfrage ausführen, Ich bekomme eine java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Boolean.

Wie muss die HQL-Abfrage aussehen, damit dies funktioniert? Ich weiß, ich könnte einfach einen Long-Wert zurückgeben und hinterher meinen Java-Code einchecken, wenn count > 0, aber diese Problemumgehung sollte nicht notwendig sein, oder?

+1

offensichtlich könnten Sie Ihre JPQL Abfrage ändern, um eine boolean ... durch nicht wiederkehrende „count (e)“ zurückzukehren und stattdessen einen Booleschen Ausdruck –

Antwort

29

Ich glaube, Sie können einfach die Abfrage ändern boolean als

@Query("select count(e)>0 from MyEntity e where ...") 

PS zurückzukehren: Wenn Sie existiert, basierend auf Primärschlüsselwert sind die Überprüfung CrudRepository bereits exists(id) Methode haben.

+0

Dank Rückkehr für der Zeiger auf 'exists (id)', aber meine where-Klausel enthält einige komplexe Einschränkungen ... –

+4

'count (e)> e' funktioniert wahrscheinlich nur mit bestimmten Datenbanken (zB Oracle). Bei DB2 ist das nicht der Fall, und Sie müssen 'execute case wenn count (e)> 0 dann true else false von Entity e' verwenden. –

2

in meinem Fall ist es nicht funktioniert wie folgt

@Query("select count(e)>0 from MyEntity e where ...") 

Sie können es als Booleschen Wert zurück, mit folgenden

@Query(value = "SELECT CASE WHEN count(pl)> 0 THEN true ELSE false END FROM PostboxLabel pl ...") 
5

Seit dem Frühjahr Daten 1.12 Sie die Abfrage durch Beispiel functionnality verwenden können Erweiterung der QueryByExampleExecutor Schnittstelle (Die JpaRepository erweitert es bereits).
Dann können Sie diese Abfrage (unter anderem) verwenden: Wenn ein Unternehmen wissen, mit diesem Namen existiert, ignoriert Fall, dann den Anruf an diese

<S extends T> boolean exists(Example<S> example); 

eine Entität Betrachten MyEntity, die als Eigenschaft name, Sie wollen Methode kann wie folgt aussehen:

//The ExampleMatcher is immutable and can be static I think 
ExampleMatcher NAME_MATCHER = ExampleMatcher.matching() 
      .withMatcher("name", GenericPropertyMatchers.ignoreCase()); 
Example<MyEntity> example = Example.<MyEntity>of(new MyEntity("example name"), NAME_MATCHER); 
boolean exists = myEntityRepository.exists(example); 
+0

In meinem Fall nicht wirklich relevant, da sich meine Abfrage in HQL befindet –

0

Abgesehen von der angenommenen Antwort, schlage ich eine andere Alternative vor. Verwenden Sie QueryDSL, erstellen Sie ein Prädikat und verwenden Sie die exists()-Methode, die ein Prädikat akzeptiert und Boolean zurückgibt.

Ein Vorteil von QueryDSL ist, dass Sie das Prädikat für komplizierte where-Klauseln verwenden können.

48

Federdaten JPA 1.11 unterstützt jetzt die exists Projektion in der Repository-Abfrageableitung.

Siehe Dokumentation here.

In Ihrem Fall folgendes funktioniert:

public interface MyEntityRepository extends CrudRepository<MyEntity, String> { 
    boolean existsByFoo(String foo); 
} 
+1

Wenn Sie eine hinzufügen Arbeitsbeispiel werde ich gerne upvote. –

+0

@StefanHaberl Ich habe ein Beispiel aufgenommen. –

+0

Ich fragte tatsächlich, wie man die HQL-Abfrage formuliert ... –

Verwandte Themen