Взаимодействие Spring Data JPA @Query annotation и Hibernate @Where annotation

#hibernate #spring-boot #spring-data-jpa

#переход в спящий режим #spring-загрузка #spring-data-jpa

Вопрос:

У меня возникла интересная проблема с @Where аннотациями и @Query аннотациями в проекте spring boot, spring data jpa также присутствует в проекте.

В принципе, у меня есть механизм мягкого удаления, и он предназначен для установки допустимой даты для объекта (скажем, valide_date столбца свойств со validDate свойством в классе Entity). Эти объекты аннотируются с помощью @Where аннотации, что-то вроде @Where("valid_date > now()") . Таким образом, автоматически удаляемые объекты, для которых valid_date установлено значение now и before, удаляются автоматически. (например, класс сущности User )

 @Entity
@Table(name = "user")
@SQLDelete(sql = "...") // to update valid date for soft deleting entity
@Where(clause="valid_date > now()") //to apply non deleted entity automatically
public class User {

    @OneToOne(...)
    BaseEntity base;
}
  

У меня также есть некоторые другие объекты, у которых нет valid_date . (например, Entity class UserRequest )

 @Entity
@Table(name = "user_request") //
public class UserRequest {

    @OneToOne(...)
    BaseEntity base;
}
  

А также некоторые другие доступные таблицы. В случае метода аннотирования запросов Jpa. Я сталкиваюсь с некоторыми проблемами.

 @Query("SELECT new com.foo.RequestListDto(B, S, I, U) from UserRequest B "  
        " left join fetch AnotherTable I on I.base = B.base"  
        " left join fetch User U on U.base = B.base"  
        " left join fetch UserRequest S on S.base = B.base "  
        " where B.id IN :idList")
  

По сути, я создаю список запросов DTO, который представляет собой набор различных свойств из разных таблиц, основанный на объединении общих свойств.

Когда вызывается метод с приведенной выше @Query аннотацией; Просматривая сгенерированный sql; Я не вижу valid_date > now () предложения, применяемого к объекту User. «ЕСЛИ» объект пользователя находится на стороне соединения, как показано выше. Если я изменю предложение from на « from User U «, то к запросу будет применено правило valid_date.

Подводя итог; @Where аннотация применяется, только если содержащий объект находится в предложении from . Но не применяется, если содержащий объект не включен в предложение from .

Есть ли конкретная причина не применять @Where аннотацию, которую я не знаю? Что я должен сделать, чтобы эта @Where аннотация применялась автоматически?

Примечание: Я могу расширить эти предложения «присоединиться к …» на join on ... and U.validDate > :now для @Where аннотированных объектов. Но единственный ли это способ?

Ответ №1:

@Where Аннотация работает именно так, как и должна работать. Только в запросах, где from является аннотируемым объектом. Если вы хотите использовать это для join , то вам также необходимо аннотировать «join-definition», которое является свойством, аннотируемым @OneToOne аннотацией. Вы также можете добавить @Where аннотацию к свойствам. Итак, добавьте @Where аннотацию к свойству User в объекте, который вы хотите использовать в from части запроса

 @OneToOne(...)
@Where(clause="valid_date > now()")
User user;
  

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

1. спасибо за ответ, но я бы не пытался присоединиться к таблице, если она уже находится в реляционно отображенном состоянии моего объекта предложения from (в данном случае UserRequest). И для меня также; У аннотации Where также есть некоторые проблемы. Поскольку в примечании к источнику Where говорится, что это в основном полезно при программном удалении. Но здесь, поскольку это не применялось на стороне объединения; также возвращались объекты, удаленные программным способом.