質問

最初に質問を設定します。

私が持っているのは、顧客、住所、注文、注文項目の4つのテーブルです。それぞれはHibernate Annotationsを使用してマップされ、Spring DAO / Servicesレイヤーを介してアクセスされます。

私がやろうとしているのは、重複した顧客をマージすることです。本当に必要なのは、顧客Bに関連付けられたすべての注文と住所、顧客Aを指すようにcustomer_id外部キーを更新する必要があることです。その後、顧客Bは無効ビットを設定する必要があります。

これらの単純なクエリをデータベースに送信する代わりに、hibernateはおかしくなり、大量のselectおよびupdateクエリを発行します。特に、注文に添付されているすべての注文アイテムを選択します(これは EAGER で定義されており、この点は変更できないためです)。更新前にselectを取得して発生を停止するには、次のように通常の javax.persistence.Entity の上にhibernateエンティティアノテーションを追加してみました:

@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出力クエリは完璧で動的です。

アイデアはありますか

役に立ちましたか?

解決

手がかりは、merge()操作の選択にある可能性があります。 Hibernate javadocから:

  

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

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

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

  

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top