«Мягкое удаление» в Hibernate с сопоставлением OneToOne

Я использую шаблон под названием «мягкое удаление». Вместо удаления объекта я просто помечаю его как удаленный и предотвращаю его появление в результатах любого запроса, добавляя @Where(clause = "rmv = false")(rmv — это имя столбца в базе данных, где я храню флаг).

В одном сценарии этот подход не работает.

Вот пример:

@Entity
@Table(name = "main_entity")
public class MainEntity {

    @Id
    private Long id;

    @OneToOne(mappedBy = "main", cascade = CascadeType.ALL)
    private DetailEntity detail;
}
 
@Entity
@Table(name = "detail_entity")
@Where(clause = "rmv = false")
public class DetailEntity{
    @Id
    private Long id;

    @Column
    private Boolean rmv = false;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "main_id", nullable = false)
    private MainEntity main;
}

Когда я пытаюсь получить экземпляр MainEntity из Hibernate с помощью mainEntityRepository.findById(id), я получаю объект с помощью detail != null. Несмотря на то, что в таблице detail_entity есть запись rmv = false.

Он создает следующий SQL-запрос

select m.*, d.* 
from main_entity m 
left join detail_entity d 
    on m.id=d.main_id 
where m.id=?

Я ожидаю, что в пункте d.rmv=false будет условие where.

Мои вопросы:

  • Это ошибка или ожидаемое поведение?
  • Если это ожидаемое поведение, есть ли способ добиться желаемого эффекта?

РЕДАКТИРОВАТЬ Версия гибернации: 6.1.7

Где аннотация @Where?

David Conrad 03.07.2024 20:07

@DavidConrad Я забыл это скопировать. Спасибо, что заметили. Я отредактировал свой вопрос.

talex 03.07.2024 20:13
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Также добавьте предложениеwhere к родительскому (MainEntity) сопоставлению OneToOne.

@Entity
@Table(name = "main_entity")
public class MainEntity {

@Id
private Long id;

@OneToOne(mappedBy = "main", cascade = CascadeType.ALL)
@Where(clause = "rmv = false")
private DetailEntity detail;
}

К сожалению, это не влияет на сгенерированный SQL.

talex 03.07.2024 20:28
Ответ принят как подходящий

Эта проблема решена в новой версии Hibernate.

Я проверил, 6.5.2 работает нормально.

Другие вопросы по теме