Какое должно быть имя метода, чтобы генерировался запрос DELETE FROM ... WHERE date < :1?
Есть Entity:
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Keys {
private @Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
String id;
private @Lob
java.security.KeyPair keyPair;
private Calendar expirationDate;
public Keys(java.security.KeyPair keyPair, Calendar expirationDate) {
this.keyPair = keyPair;
this.expirationDate = expirationDate;
}
}
И репозиторий:
public interface KeysRepository extends JpaRepository<Keys, String> {
}
Необходимо выполнять операцию удаления всех Keys, у которых expirationDate раньше переданного времени. Очевидно, что этой задаче соответствует запрос DELETE FROM Keys WHERE expirationDate < :1. Но при добавлении в интерфейс методов deleteAllByExpirationDateBefore(Calendar date), deleteKeysByExpirationDateBefore(Calendar date), deleteByExpirationDateBefore(Calendar date) логируются запросы:
Hibernate:
select
keys0_.id as id1_0_,
keys0_.expiration_date as expirati2_0_,
keys0_.key_pair as key_pair3_0_
from
keys keys0_
where
keys0_.expiration_date<?
Hibernate:
delete
from
keys
where
id=?
Т.е., вместо простого DROP FROM Keys WHERE expiration_date < ? выполняется сначала select всех удовлетворяющих, а после этого они удаляются по одному (delete from keys where id=?).
Вопрос: Как сделать так, чтобы при вызове метода выполнялся запрос delete from keys where expiration_date < ?? Без использования аннотации @Query.
Ответы (1 шт):
Автоматически сгенерированные методы deleteBy* всегда сначала читают данные отдельным запросом, а потом удаляют по одному.
Причина этого описана в документации, а именно, это сделано для того, чтоб можно было вызвать обработчики @PreRemove и таким образом, чтоб поведение этого способа удаления было таким же как и delete.
derived delete query is a shortcut for running the query and then calling CrudRepository.delete(Iterable users) on the result and keeping behavior in sync with the implementations of other delete(…) methods in CrudRepository
Так что без использования @Query + @Modifying не обойтись (имя метода в этом случае не имеет значения):
@Modifying
@Query("delete from Keys k where k. expirationDate < :date")
void deleteKeysByExpirationDateBefore(@Param("date") String date);