1

次のコードがあります。

println "@@@@@@@@ RUNNING ProfessionaCustomer - ${pcCounter} under ${accountCustomer.customerNumber}  Professional SQLid ${it.id}"
def professionalCustomerId = it.customerId
def professionalCustomer = ProfessionalCustomer.findByCustomerNumber(professionalCustomerId)

SQL ログオンがあり、次のようになります。

@@@@@@@@ RUNNING ProfessionaCustomer - 31 under 106450  Professional SQLid 100759
Hibernate: update base_domain set version=?, account_name=?, address_line1=?,  address_line2=?, city=?, customer_number=?, date_created=?, disabled=?, last_updated=?, postal_code=?, primary_phone=?, state_or_province=? where id=? and version=?
Hibernate: update base_domain set version=?, address1=?, address2=?, city=?, customer_number=?, date_created=?, disabled=?, first_name=?, last_name=?, last_updated=?, middle_name=?, phone_number=?, postal_code=?, state=? where id=? and version=?
Hibernate: insert into account_customer_professionals (account_customer_id, professional_customer_id) values (?, ?)
Hibernate: select this_.id as id1_3_0_, this_.version as version2_3_0_, this_.address1 as address70_3_0_, this_.address2 as address71_3_0_, this_.city as city7_3_0_, this_.customer_number as customer8_3_0_, this_.date_created as date_cre9_3_0_, this_.disabled as disable10_3_0_, this_.first_name as first_n19_3_0_, this_.last_name as last_na20_3_0_, this_.last_updated as last_up11_3_0_, this_.middle_name as middle_72_3_0_, this_.phone_number as phone_n73_3_0_, this_.postal_code as postal_12_3_0_, this_.state as state74_3_0_ from base_domain this_ where this_.class='com.eveo.nplate.model.ProfessionalCustomer' and this_.customer_number=? limit ?

DBを更新しています。これでなぜこれが遅いのか説明できますが、これが起こる理由はわかりません。

「findBy」によって更新が発生するのはなぜですか?

4

2 に答える 2

2

Hibernate は、必要があると判断するまで作成、更新、または削除をすぐに実行しません。できる限り長く待機し (かなり悲観的ですが)、指示されたとき、または必要と判断したときにのみ、これらの変更をフラッシュします。一般に、明示的な呼び出しなしでフラッシュされるのは、クエリを実行するときだけです。これは、メモリ内にある新しいインスタンス、更新されたインスタンス、および削除されたインスタンス (Hibernate セッション、第1レベルのキャッシュにキャッシュされている) のいずれかがクエリ結果に影響を与える可能性があるためです。クエリに対して適切な結果を取得します。

これに対する 1 つの例外はsave()、新しいインスタンスの呼び出しです。Grails はこれをフラッシュします。通常、ID は自動インクリメント列またはシーケンスを介してデータベースによって割り当てられるためです。メモリ内の状態がデータベースと同じであることを確認するために、save()呼び出しをフラッシュして、ID を取得してインスタンスに設定できるようにします。ただし、永続化インスタンスを取得して (たとえば、get()呼び出し、基準クエリ、ファインダーなどを使用して) 変更した場合、その呼び出しsave()は自動的にフラッシュされません。同じことがdelete()呼び出しにも当てはまります - フラッシュされません。

永続インスタンスの呼び出しは、アクションを「最終的に」実行する必要があるという Hibernate へのメッセージとdelete()考えてください。save()

そのため、ファインダー、条件、「where」、または HQL クエリを実行すると、Hibernate はフラッシュされていない変更をフラッシュします。これが発生したくない場合 (カスタム ドメイン クラス バリデータ クロージャなど)、別のセッションでクエリを実行できます (たとえばwithNewSessionメソッドを使用)。

インスタンスで明示的に、または or呼び出しにSession追加flush:trueして、セッションをまったくフラッシュしない場合、セッションはフラッシュされます。Grails は、各リクエストの開始時にセッションを開始する OpenSessionInView インターセプターを登録し、最後に閉じます。これは遅延読み込みに役立ちます。セッションが開いていて既知の場所にバインドされているため、Hibernate と GORM (Spring を介して) はその開いているセッションを使用して、クエリの実行後に遅延ロードされたコレクションとインスタンスをオンデマンドで取得できます。savedeleteThreadLocalHibernateTemplate

トランザクションでフラッシュする必要がないことにも注意してください。トランザクション マネージャーは、HibernateTransactionManagerコミットする前にフラッシュする Spring です。

于 2015-01-11T03:40:59.957 に答える
1

おそらく、データベースに永続化されていないトランザクションがセッションにありました。

休止状態を実行findByすると、接続を利用して 2 つのクエリが実行されます。これが起こったことだと思います。

于 2015-01-09T10:36:07.140 に答える