私は休止状態に関してかなりのピクルスに自分自身を見つけました。私は自分のWebアプリケーションの開発を開始したときにどこにいても "熱心な"読み込みをしていましたので、子供、両親などに簡単にアクセスできました。Hibernateグッドプラクティス、レイジー/ eagerローディングとセーブ/削除の子供たち(助けて私を助けてください)
しばらくして、削除されたオブジェクトを再保存しました。複数のstackoverflowスレッドは、オブジェクトをすべてのコレクションから削除しなければならないことを示唆しました。これらの提案を読むことは、私の関係が本当にシンプルではなく、私のコードを一種のように見せかける複数のオブジェクトを反復しなければならなかった醜いと私はこれが最高のアプローチだったかどうか疑問に思った。
たとえば、Employee(ユーザーが複数の異なる従業員として行動できるという意味でUserに属している)を削除する場合。従業員がフィードバックを党に残すことができるので、従業員は複数のフィードバックを持ち、党は複数のフィードバックを持つことができます。また、EmployeeとPartyの両方が何らかの親オブジェクトに属しているとします。基本的に、我々は持っている:
class User {
// Has many
Set<Employee> employees;
// Has many
Set<Organization> organizations;
// Has many through employees
Set<Organization> associatedOrganizations;
}
class Employee {
// Belongs to
User user;
// Belongs to
Organization organization;
// Has many
Set<Feedback> feedbacks;
}
class Organization {
// Belongs to
User user;
// Has many
Set<Employee> employees;
// Has many
Set<Party> parties;
}
class Party {
// Belongs to
Organization organization;
// Has many
Set<Feedback> feedbacks;
}
class Feedback {
// Belongs to
Party party;
// Belongs to
Employee employee;
}
をここで私は、従業員を削除するときになってしまったものです:
// First remove feedbacks related to employee
Iterator<Feedback> iter = employee.getFeedbacks().iterator();
while (iter.hasNext()) {
Feedback feedback = iter.next();
iter.remove();
feedback.getParty().getFeedbacks().remove(feedback);
session.delete(feedback);
}
session.update(employee);
// Now remove employee from organization
Organization organization = employee.getOrganization();
organization.getEmployees().remove(employee);
session.update(organization);
これは、私の定義によって、醜いです。ためには、
Error during managed flush [deleted object would be re-saved by cascade (remove deleted object from associations)
ので:代わりに私が手
session.delete(employee);
を:私は
@Cascade({CascadeType.ALL})
を使用して、その後、Hibernateは魔法のように単純に実行してすべての関連付けから従業員を削除することを想定しただろう私のコードを少し洗練されたものにしようとすると(たぶん怠惰なフェッチで十分です、時には私は熱望が必要です)、私はほとんどすべてをフェッチして、私の場合、例えば:
employee.getFeedbacks()
は、フィードバックは何の問題もなく、いや、すべての切れ目なしにうまく取り込まれ:
failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session
私が考えた次のことは、オブジェクトのための可能性を取り除いた削除/その関連子供を挿入するが、オブジェクト
child.parent=parent
の代わりに個別にすべてのオブジェクトを挿入する - それはおそらく悪いアイデアのパフォーマンスが賢明だろうバルクでは
parent.children().add(children)
となります。
最後に、私は、複数の人が独自のカスタムクエリやものを作成することを推奨していましたが、その時点で、なぜHibernateを気にする必要がありますか?私の問題を比較的きれいに扱う良い方法はないのですか、何かを逃したり、私はばかですか?
一般的に言えば、FETCH JOINを使用していつでも気軽に切り替えることができますが、熱心な負荷を遅延させることはできません。 Hibernateは、見た目よりも扱いにくいです。経験の少ないプログラマーには、「すべてが魔法によって保存されるため、データベースを理解する必要はありません」という驚きがしばしばあります。残念ながら、これは非常に単純な使い方にとどまります。 – Kayaman
しかし、特定のクエリ、注釈だけがない場合、フェッチ結合についてはどうすればよいですか? – Salkz
これは私が言及していた「非常に簡単な使い方」です。特別なクエリを持たない複雑な機能を構築することは期待できません。たとえそれがうまく動作しても、それは絶対に性能を破壊するでしょう。 – Kayaman