开发者

Filter JPA Entities without removing them from database

开发者 https://www.devze.com 2023-03-23 18:13 出处:网络
i have a database table \"viewmodule\" with a FK to itself (parent_id) to allow recursive structures.

i have a database table "viewmodule" with a FK to itself (parent_id) to allow recursive structures.

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

My Java application uses JPA/Hibernate to map the entities on that table. We have fixed entity hirachy which is solved by a @Discriminator annotation that uses the "type" column of the table.

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;
(...)
}

My task is now to load all elements from this table (in deep) but left out the ones which have the field "hide" set to true. It开发者_JAVA技巧s a apparently simple filter mechanism. My first approach was to use the Hibernate Filter annotation, which works well on the first layer (all viewmodules with parent_id = null). But the filter does not work on the "children" relation. (In my real life model, i have an inheritance structure for the different types of the ViewModules)

Therefore i've written a small function that recursively walks through the viewModule object tree and removes the viewModules from the children relation that have hide=true;

But, as all objects are still under observation of the jpa/hibernate entityManager, every remove from a collection is directly executed as delete in the database. So my filter function removes the entity from the database, and that is a bad thing.

I tried to use the "evict" method from the hibernate session to detach the entities before filtering but that leads to a LazyInitialisationException.

So, to prevent cloning all of my object my question is how to solve this problem? Is there a way to detach the object in way that all collections are initialized? Or is there a special Kung-Fu Chuck-Norris JPA Annotation that can filter the collections?

Thanks in advance


use native query

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

This works: Filter list contained in entity returned by jpa/hibernate query


Make a new collection and add only the elements that have hide=false. You won't be able to distribute that collection together with the object, so you'd have to return it from a separate method call. For example: dao.getVisibleItems(module)

Another thing - you can remove the Cascade.DELETE (i.e. list all cascades except delete) and the orphan removal, if you don't need them.

0

精彩评论

暂无评论...
验证码 换一张
取 消