I'm implementing the soft delete logic for my entities using Spring and Hibernate. I use @Filter Hibernate annotation to perform this logic. But there is a problem I cannot resolve: the objects in lazy loaded collections are not being filtered.
The code is quite simple:
@Entity
@Table(name = "orders")
public class Order {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
@Filter(name = "deletedOrderItemFilter", condition = "0 = deleted")
private Set<OrderItem> orderItems;
// getter and setter
}
@Entity
@Table(name = "order_item")
@FilterDef(name = "deletedOrderItemFilter", defaultCondition = "0 = deleted")
public class OrderItem {
@ManyToOne
@JoinColumn(name = "orderId", nullable = false)
private Order order;
@Column(name = "deleted")
private boolean deleted;
// getters and setters
}
So the logic is "when opening an Order object don't show removed OrderItems" Here is the method in DAO which returns the Session object. The Session factory is Spring's org.springframework.orm.hibernate4.LocalSessionFactoryBean.
public Session getSession() {
Session session = sessionFactory.getCurrentSession();
session.enableFilter("deletedOrderItemFilter");
return session;
}
So this method is being called only explicitly - when I request the List of Orders. But what's interesting is that the PersistenceSet for my orderItems List seems to have a null Session (it's strange 'cause I am not getting any LazyInitializationException
). So the filter "deletedOrderItemFilter" is not applied to the orderItems
List.
I've googled it of course and I've found out that as soon as the Transaction in which I get the Orders List is closed, the Session is closed too. But still I cannot find any solution. I've tried to explicitly assign a new temporary Session to the PersistenceSet (when fetching it) but still no luck (although the session factory seemed to have my filter in the filters list).
Any help would be appreciated.
UPDATE OK I can solve it the "dirty" way:
OrderItem
implemets my own interfaceRemovable
with method likeisRemoved
- in the
orderItems
getter call common filtering method iterating through the items and filtering them. The downside is that I would have to load all the objects - deleted and not - from the database.
UPDATE
I'm not getting any LazyInitializationException
because of the sessionFactory Spring bean config property:
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
So I guess: no transaction - no session - no filters applied.