0

最初に質問を設定しましょう。

私が持っているのは、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 出力クエリは完璧で動的です。

何か案は?

4

1 に答える 1

2

手がかりは、merge() 操作の選択にあるかもしれません。Hibernate javadoc から:

指定されたオブジェクトの状態を、同じ識別子を持つ永続オブジェクトにコピーします。セッションに現在関連付けられている永続インスタンスがない場合は、ロードされます。

したがって、変更する前に Hibernate にすべてのデータをロードするように強制しています。

update() などの別の操作を試してください。

指定された切り離されたインスタンスの識別子で永続インスタンスを更新します。

約束はありませんが、Hibernate はとにかくそれをロードする必要があると判断するかもしれません。dynamicUpdates=true 構成は、動的更新を発行する前に何を開始する必要があるかを知る必要があるため、実際にはさらに悪化する可能性があります。

于 2009-06-17T21:12:39.113 に答える