我正在使用 Spring 和 Hibernate 为我的实体实现软删除逻辑。我使用@Filter Hibernate 注释来执行这个逻辑。但是有一个我无法解决的问题:延迟加载的集合中的对象没有被过滤。
代码很简单:
@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
}
所以逻辑是“在打开Order对象时不显示已删除的OrderItem s” 这是 DAO 中返回 Session 对象的方法。Session 工厂是 Spring 的 org.springframework.orm.hibernate4.LocalSessionFactoryBean。
public Session getSession() {
Session session = sessionFactory.getCurrentSession();
session.enableFilter("deletedOrderItemFilter");
return session;
}
因此,仅当我请求 List of Order时才显式调用此方法。但有趣的是,我的orderItems List 的 PersistenceSet 似乎有一个null Session (这很奇怪,因为我没有得到任何 Session LazyInitializationException
)。所以过滤器“deletedOrderItemFilter”不应用于orderItems
列表。
我当然已经用谷歌搜索过了,我发现一旦我获得订单列表的交易关闭,会话也关闭。但我仍然找不到任何解决方案。我试图显式地为 PersistenceSet 分配一个新的临时会话(在获取它时),但仍然没有运气(尽管会话工厂似乎在过滤器列表中有我的过滤器)。
任何帮助,将不胜感激。
更新好的我可以用“脏”的方式解决它:
OrderItem
Removable
用类似的方法实现我自己的接口isRemoved
- 在
orderItems
getter 调用通用过滤方法中迭代项目并过滤它们。缺点是我必须从数据库中加载所有对象 - 已删除而不是未删除。
更新LazyInitializationException
由于 sessionFactory Spring bean 配置属性,
我没有得到任何信息:
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
所以我猜:没有交易 - 没有会话 - 没有应用过滤器。