Репозиторий JPA найти по полю даты только за определенный месяц

#java #spring #jpa

Вопрос:

У меня есть сущность, у которой есть LocalDateTime поле. Я хочу запросить эти сущности по месяцу этого поля даты. У меня есть следующий запрос:

 List<MyEntity> findAllByDate_MonthValue(Integer monthValue)
 

Это не работает, это приводит к следующей ошибке:

орг.пружинная конструкция.фасоль.фабрика.Исключение BeanCreationException: Ошибка при создании компонента с именем «MyEntityRepository»: FactoryBean создал исключение при создании объекта; вложенное исключение-java.lang.Исключение IllegalArgumentException: Не удалось создать запрос для метода public abstract java.util.Перечислите значение MyEntityRepository.findAllByDate_MonthValue(целое число)! Незаконная попытка разыменования источника пути [null.дата] базового типа

Я не понимаю ошибки, я пробовал другие подходы, и ни один не сработал. Более того, я пытался использовать @Query аннотацию, но у меня нет YEAR/MONTH/etc... and neither EXTRACT функций.

Комментарии:

1. but I don't have the YEAR/MONTH/etc... and neither EXTRACT functions. почему?

2. Intellij, похоже, не заполняет их автоматически, и при их использовании я получаю ошибки компиляции, поэтому я действительно не знаю, почему. Я вижу, что они специфичны для зимней спячки, я сам толком не знаю.

3. ну, вы все равно можете использовать собственный запрос (написанный на SQL или любом другом языке, который поддерживает ваша СУБД).

Ответ №1:

Вы не можете использовать ссылку на месяц.

Вам нужно преобразовать свой запрос во что-то вроде:

 findAllByDateBetween
 

этот метод будет принимать две даты, которые используются в качестве второстепенного и основного предела запроса. Поэтому вам нужно создать метод, чтобы получить первый день месяца и первый день следующего месяца, чтобы правильно вызвать этот метод.

Полный список всех ключевых слов, принятых в методах JPA, доступен здесь, а ссылка на ключевое слово Between приведена ниже:

 Keyword    Example                  JPQL Snippet
---------------------------------------------------
Between    findByStartDateBetween   ... where x.startDate between ?1 and ?2
 

Ответ №2:

Предполагая, что вы используете Hibernate в качестве поставщика ORM, вы можете использовать HQL и запрос, аналогичный этому, чтобы извлечь значение месяца из заданной даты и сравнить его с заданным целочисленным значением. Рассмотрим следующий пример:

  1. Класс сущностей
 @Table(name = "SomeEntity")
@Entity(name = "SomeEntity")
@Data
public class SomeEntityClass {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String someColumn;

    @Basic
    private ZonedDateTime someDate;

}
 

И следующий интерфейс репозитория:

  1. Хранилище
 public interface SomeEntityRepository extends JpaRepository<SomeEntityClass, Long> {

    @Query(
        name = "SomeEntityClass.findAllByMonth",
        value = "SELECT E FROM SomeEntity E WHERE MONTH(E.someDate) = :monthValue"
    )
    List<SomeEntityClass> findAllByMonth(@Param("monthValue") Integer monthValue);

}
 

Я надеюсь, что это что-то полезное для вас.