web-dev-qa-db-de.com

Spring Data JPA und Exists Abfrage

Ich verwende Spring Data JPA (mit Hibernate als JPA-Anbieter) und möchte eine exists-Methode mit einer angefügten HQL-Abfrage definieren:

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 starte, erhalte ich einen 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 anschließend meinen Java-Code auf count > 0 überprüfen, aber diese Problemumgehung sollte nicht erforderlich sein, oder? 

36
Stefan Haberl

Ich denke, Sie können die Abfrage einfach ändern, um Boolean als zurückzugeben

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

PS: Wenn Sie prüfen, ob der Primärschlüsselwert CrudRepository bereits vorhanden ist, verwenden Sie die exists(id)-Methode.

46

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

Siehe Dokumentation hier .

In Ihrem Fall wird Folgendes funktionieren:

public interface MyEntityRepository extends CrudRepository<MyEntity, String> {  
    boolean existsByFoo(String foo);
}
108
Ankit Soni

Seit Spring data 1.12 können Sie die Abfrage mit der Beispielfunktionalität verwenden, indem Sie die QueryByExampleExecutor-Schnittstelle erweitern (die JpaRepositoryalready erweitert sie).
.__ Dann können Sie (unter anderem) diese Abfrage verwenden: 

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

Betrachten Sie eine Entität MyEntity, die als Eigenschaft name wissen soll, ob eine Entität mit diesem Namen vorhanden ist, wobei Groß-/Kleinschreibung ignoriert wird. Der Aufruf dieser Methode kann dann folgendermaßen 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);
8
Stephane L

in meinem Fall funktionierte es nicht wie folgt 

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

Sie können es mit boolean als Wert zurückgeben

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

Abgesehen von der akzeptierten Antwort schlage ich eine weitere 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.

1
Narasimha

Sie können den Ausdruck Case verwenden, um eine boolean in Ihrer Auswahlabfrage wie folgt zurückzugeben.

@Query("SELECT CASE WHEN count(e) > 0 THEN true ELSE false END FROM MyEntity e where e.my_column = ?1")
0
Sahil Chhabra