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.