J'utilise Spring Data JPA (avec Hibernate en tant que fournisseur JPA) et je souhaite définir une méthode exists
avec une requête HQL attachée:
public interface MyEntityRepository extends CrudRepository<MyEntity, String> {
@Query("select count(e) from MyEntity e where ...")
public boolean existsIfBlaBla(@Param("id") String id);
}
Lorsque je lance cette requête, je reçois un Java.lang.ClassCastException: Java.lang.Long cannot be cast to Java.lang.Boolean
.
À quoi doit ressembler la requête HQL pour que cela fonctionne? Je sais que je pourrais simplement renvoyer une valeur Long et ensuite vérifier dans mon code Java si count > 0
, mais cette solution de contournement ne devrait pas être nécessaire, non?
Je pense que vous pouvez simplement changer la requête pour retourner un booléen
@Query("select count(e)>0 from MyEntity e where ...")
PS: Si vous vérifiez qu’il existe en fonction de la valeur de la clé primaire CrudRepository
, vous avez déjà la méthode exists(id)
.
Spring Data JPA 1.11 prend désormais en charge la projection exists
dans la dérivation de la requête du référentiel.
Voir la documentation ici .
Dans votre cas, ce qui suit fonctionnera:
public interface MyEntityRepository extends CrudRepository<MyEntity, String> {
boolean existsByFoo(String foo);
}
Depuis Spring data 1.12, vous pouvez utiliser la fonctionnalité de la requête par exemple en étendant l'interface QueryByExampleExecutor
(la JpaRepository
already l'étend).
Ensuite, vous pouvez utiliser cette requête (entre autres):
<S extends T> boolean exists(Example<S> example);
Considérons une entité MyEntity
qui, en tant que propriété name
, souhaite savoir si une entité portant ce nom existe, en ignorant la casse, l'appel à cette méthode peut alors ressembler à ceci:
//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);
dans mon cas, cela n'a pas fonctionné comme suit
@Query("select count(e)>0 from MyEntity e where ...")
Vous pouvez le renvoyer en valeur booléenne en suivant
@Query(value = "SELECT CASE WHEN count(pl)> 0 THEN true ELSE false END FROM PostboxLabel pl ...")
Outre la réponse acceptée, je suggère une autre alternative . Utilisez QueryDSL , créez un prédicat et utilisez la méthode exists()
qui accepte un prédicat et retourne un booléen.
Un avantage avec QueryDSL est que vous pouvez utiliser le prédicat pour les clauses where compliquées.
Vous pouvez utiliser l'expression Case
pour renvoyer une boolean
dans votre requête select, comme ci-dessous.
@Query("SELECT CASE WHEN count(e) > 0 THEN true ELSE false END FROM MyEntity e where e.my_column = ?1")