Фильтрация объектов JPA без удаления их из базы данных - PullRequest
3 голосов
/ 27 июля 2011

У меня есть таблица базы данных "viewmodule" с FK для себя (parent_id), чтобы разрешить рекурсивные структуры.

CREATE TABLE viewmodule (
id,
type,
parent_id,
hide);

Мое Java-приложение использует JPA / Hibernate для сопоставления сущностей в этой таблице.Мы исправили хирачность сущностей, которая решается аннотацией @Discriminator, которая использует столбец «type» таблицы.

public class ViewModule implements Serializable {
   private long id;
   private String type;
   private ViewModule parent;
   private Boolean hide;

   @OneToMany( targetEntity = ViewModule.class, cascade = javax.persistence.CascadeType.ALL, mappedBy = "parent" )
   @Cascade( { org.hibernate.annotations.CascadeType.ALL,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN } )
   private Set<ViewModules> children;
(...)
}

Теперь моя задача - загрузить все элементы из этой таблицы (в глубине), но осталосьиз тех, у которых поле «скрыть» установлено в значение «истина».Это очевидно простой механизм фильтрации.Мой первый подход состоял в том, чтобы использовать аннотацию Hibernate Filter, которая хорошо работает на первом слое (все viewmodules с parent_id = null).Но фильтр не работает с отношением «дети».(В моей реальной модели у меня есть структура наследования для различных типов ViewModules)

Поэтому я написал небольшую функцию, которая рекурсивно проходит по дереву объектов viewModule и удаляет viewModules из дочерних отношенийкоторые имеют hide = true;

Но, поскольку все объекты все еще находятся под наблюдением jpa / hibernate entityManager, каждое удаление из коллекции напрямую выполняется как удаление в базе данных.Поэтому моя функция фильтра удаляет сущность из базы данных, и это плохо.

Я пытался использовать метод «evict» из сеанса гибернации для отсоединения сущностей до фильтрации, но это приводит к исключению LazyInitialisationException.

Итак, чтобы предотвратить клонирование всего моего объекта, мой вопрос заключается в том, как решить эту проблему?Есть ли способ отсоединить объект так, чтобы все коллекции были инициализированы?Или существует специальная аннотация кунг-фу Чака-Норриса JPA, которая может фильтровать коллекции?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 27 июля 2011

использовать собственный запрос

em.createNativeQuery("select * from viewmodule where hide = false", ViewModule.class).getResultList();

Это работает: Список фильтров, содержащийся в объекте, возвращенном запросом jpa / hibernate

0 голосов
/ 27 июля 2011

Создайте новую коллекцию и добавьте только те элементы, которые имеют hide=false.Вы не сможете распространять эту коллекцию вместе с объектом, поэтому вам придется возвращать ее из отдельного вызова метода.Например: dao.getVisibleItems(module)

Другое дело - вы можете удалить Cascade.DELETE (то есть перечислить все каскады, кроме удаления) и удалить потерянные, если они вам не нужны.

...