Spring Запрос данных JPA и Exists

Я использую Data JPA (с Hibernate как мой поставщик JPA) и хочу определить метод exists с прилагаемым запросом HQL:

public interface MyEntityRepository extends CrudRepository<MyEntity, String> {

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

}

Когда я запускаю этот запрос, я получаю java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Boolean.

Как выглядит запрос HQL, чтобы заставить эту работу работать? Я знаю, что могу просто вернуть значение Long, а затем проверить свой код Java, если count > 0, но это обходное решение не должно быть необходимым, не так ли?

Ответы

Ответ 1

Я думаю, вы можете просто изменить запрос, чтобы возвращать boolean как

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

PS: Если вы проверяете существование на основе значения основного ключа CrudRepository, уже есть метод exists(id).

Ответ 2

Spring Данные JPA 1.11 теперь поддерживают проектирование exists в выводе запроса репозитория.

См. документацию здесь.

В вашем случае будет работать следующее:

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

Ответ 3

Так как Spring данные 1.12, вы можете использовать запрос по функции Function, расширив интерфейс QueryByExampleExecutor (JpaRepository уже расширяет его).
Затем вы можете использовать этот запрос (среди прочих):

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

Рассмотрим объект MyEntity, который как свойство name, вы хотите знать, существует ли сущность с этим именем, игнорируя регистр, тогда вызов этого метода может выглядеть следующим образом:

//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);

Ответ 4

в моем случае это не сработало, как после

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

Вы можете вернуть его как логическое значение со следующими

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

Ответ 5

Помимо принятого ответа, я предлагаю другую альтернативу. Используйте QueryDSL, создайте предикат и используйте метод exists(), который принимает предикат и возвращает Boolean.

Одно из преимуществ QueryDSL заключается в том, что вы можете использовать предикат для сложных предложений where.