最初に質問を設定しましょう。
私が持っているのは、Customer、Address、Order、OrderItems の 4 つ以上のテーブルです。それぞれが Hibernate Annotations を使用してマップされ、Spring DAO/Services レイヤーを介してアクセスされます。
私がやろうとしているのは、重複した顧客をまとめることです。したがって、実際に行う必要があるのは、顧客 B に関連付けられたすべての注文と住所であり、顧客 A を指すように customer_id 外部キーを更新する必要があります。次に、顧客 B に無効ビットを設定する必要があります。
これらの単純なクエリをデータベースに送信する代わりに、Hibernate はおかしくなり、大量の選択と更新のクエリを発行します。特に、注文に関連付けられたすべての注文項目を選択します (これは 定義されEAGER
ており、この点は変更できないためです)。更新前に選択を取得して停止するために、次のような通常の上に休止状態エンティティ注釈を追加しようとしましたjavax.persistence.Entity
:
@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = false, dynamicInsert = true)
これは、テーブル内の単一のアイテムのみを更新する単純なクエリを除いて、何の影響もないように見えました。
次の休止状態基準を使用してオブジェクトを取得します。
Criteria c1 = null;
Criteria c2 = null;
Criteria c = session.createCriteria(Customer.class);
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
if(resultLimit>0) c.setMaxResults(resultLimit);
if(timeout>0) c.setTimeout(timeout);
for(String filter: sqlFilters) {
if(filter.indexOf("{alias}.customer_")!=-1) c.add(Restrictions.sqlRestriction(filter));
else if(filter.indexOf("{alias}.address_")!=-1 && addrsAttached) {
if(c1==null)
c1 = c.createCriteria("addresses").setFetchMode("type", FetchMode.JOIN);
c1.add(Restrictions.sqlRestriction(filter));
} else if(filter.indexOf("{alias}.order_")!=-1 && ordersAttached) {
if(c2==null)
c2 = c.createCriteria("orders").setFetchMode("orderItems", FetchMode.SELECT);
c2.add(Restrictions.sqlRestriction(filter));
}
}
return (List<Customer>) c.list();
次に、すべての住所と注文オブジェクトを顧客 B から顧客 A に移動し、
return (Customer) this.getHibernateTemplate().merge(customer);
両方の顧客オブジェクトで。これにより、関連付けられたすべてのオブジェクト (つまり、OrderItems、Products、ProductType、ProductPricingTmpl など) を取得する大量の select ステートメントが作成されます。
これらの選択を削除する必要があります! それらがなければ、クエリは正常に見えて効率的です! Update 出力クエリは完璧で動的です。
何か案は?