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が表示されない」ということです。これは、Session オブジェクトを返す DAO のメソッドです。セッション ファクトリは、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 があるように見えることです (何も取得していないため、奇妙なことですLazyInitializationException
)。そのため、フィルター「deletedOrderItemFilter」はorderItems
リストに適用されません。
もちろん、私はそれをグーグルで検索しましたが、注文のリストを取得したトランザクションが閉じられるとすぐに、セッションも閉じられることがわかりました。しかし、それでも私は解決策を見つけることができません。新しい一時セッションを PersistenceSet に明示的に割り当てようとしましたが (フェッチするとき)、まだ運がありません (ただし、セッション ファクトリのフィルター リストにフィルターが含まれているようです)。
どんな助けでも大歓迎です。
UPDATE OK私はそれを「汚い」方法で解決できます:
OrderItem
Removable
次のようなメソッドを使用して独自のインターフェイスを実装しますisRemoved
- getterでは、
orderItems
共通のフィルタリング メソッドを呼び出して、アイテムを繰り返し処理し、それらをフィルタリングします。欠点は、すべてのオブジェクト (削除されたものとそうでないもの) をデータベースからロードする必要があることです。
更新LazyInitializationException
sessionFactory Spring Bean 構成プロパティのため、
何も取得していません。
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
だから私は推測します:トランザクションなし - セッションなし - フィルタは適用されません。