(転送)Hibernateでの逆の使用



Use Inverse Hibernate



元の: http://blog.csdn.net/xiaoxian8023/article/details/15380529

まず、Inverseは、休止状態の双方向の関係における基本的な概念です。インバースの本当の役割は、どちらのパーティがそれらの間の関係を維持するかを指定することです。一方の当事者が「inverse = false」(デフォルト)を指定した場合、その当事者は、それらの間の関係に責任を負う責任があります。率直に言って、hibernateが関連するレコードを維持するためにSQLを生成する方法!

Hibernateは、マスターオブジェクトの状態に従ってデータベースを同期的に更新するだけです。元のマッピングファイルによると、people.getAddresses()。add(address)、つまりマスターオブジェクトの状態が変更されたため、データベースはオブジェクトの状態とアドレスの変更に同期してデータベースを更新します。setPeople(人々)、すなわち、制御されているオブジェクトの状態が変更されました。オブジェクトとデータベースの同期更新をトリガーすることはできません。

(例1):



最も単純な1対多の父と息子の関係を与えます。次に、コードは次のように記述されます。

Parent p = new Parent() Child c = new Child() c.setParent(p) //Maintain the relationship between father and son p.getChildren().add(c) session.save(p) session.flush()

マッピングファイルの構成:



Hibernate: insert into parent (id) values (?) Hibernate: insert into child (parent_id, id) values (?, ?)

セット内のInverse = 'true'は、親子関係が一方の端(子)でのみ維持されることを示します。したがって、2つの挿入ステートメントのみが発行されます。

注:{many-to-one}は常に 'inverse = false'に設定されており、この属性はマッピングには存在しません。

この操作の結果は次のとおりです。



Hibernate: insert into parent (id) values (?)

セットのinverseがtrueに設定されている場合、3つのsqlステートメントが発行され、最初の2つは挿入ステートメントであり、最後の1つは親クラスと子クラスの間の親子関係を維持するために使用される更新ステートメントです。

もちろん、c.setParent(p)がコメントアウトされている(親子関係が壊れている)場合、結果は次のようになります。

Session session = HibernateUtil.getSessionFactory().getCurrentSession() session.beginTransaction() Person p = (Person) session.load(Person.class, personId) Event e = (Event) session.load(Event.class, eventId) p.getEvents().add(e)//When the code is executed, hibernate will insert the person_id and event_id records into the intermediate table person_event. If it is replaced by e.getParticipants().add(p), the code will not Will be executed, ie hibernate will not insert records into the table person_event. session.getTransaction().commit()

− =
(例2):
1人の人は複数のイベントに参加でき、1つのイベントには複数の人がいます。マッピングファイルは次のとおりです。

|_+_|

reverse = trueの意味:アソシエーションは双方向アソシエーションの相手方によって維持され、アソシエーションはパーティによって維持されません(クエリ操作のみを実行できます)。上記のコードでは、関係は個人側によって維持されます。サンプルコードは次のとおりです(Personが参加するイベントに新しいイベントを追加する場合)。

Relationship mapping in father {set name='children' lazy='true' inverse='true'} {key column='parent_id'/} {one-to-many class='test.Child'/} {/set} Son relationship mapping {many-to-one name='parent' column='parent_id' not-null='true'/} 

注意すべき1つのこと:双方向の関連付けでは、マップされた列(およびテーブル)の値は同じである必要があります(つまり、同じテーブル名と列名を使用する)。そうでない場合、inverse = 'true'に設定されたパーティは失われます。この双方向。関係は一方向の関連付けになります。

第二に、インバースとカスケードの比較


逆:関係を制御する責任があります。デフォルトはfalseです。つまり、関係の両端を制御できますが、これによりいくつかの問題が発生します。更新時には、関係が両端で制御されるため、更新が繰り返されます。通常、一方の端をtrueに設定する必要があります。

カスケード:更新、削除など、関連するオブジェクトのカスケード操作を制御します。つまり、オブジェクトが更新または削除されると、他のオブジェクトも影響を受けます。たとえば、オブジェクトを削除すると、それは多対1の関係になります。オブジェクトもすべて削除されます。
たとえば、違いは次のとおりです。「1」の終わりにあるオブジェクトOを削除する場合、「複数」の終わりの逆がtrueに設定されていると、Oに関連付けられているすべてのオブジェクトの外部キーが最後に空になります。 of'multiple''multiple 'の終わりのCascadeはDeleteに設定され、' many 'の終わりのOに関連付けられたすべてのオブジェクトが削除されます。