私は新しい Java Web アプリケーションを開発しており、データを永続化するための新しい方法 (私にとっては新しい!) を模索しています。私は主にJPAとHibernateの経験がありますが、単純なケースを除いて、この種の完全なORMは非常に複雑になる可能性があると思います. さらに、私は彼らと一緒に仕事をするのがあまり好きではありません。おそらくSQLに近い新しいソリューションを探しています。
私が現在調査している解決策:
- マイバティス
- ジューク
- プレーン SQL/ JDBC。DbUtilsまたはその他の基本的なユーティリティ ライブラリを使用する可能性があります。
しかし、Hibernate と比較して、これらのソリューションには 2 つのユース ケースについて懸念があります。これらのユースケースで推奨されるパターンを知りたいです。
ユース ケース 1 - エンティティを取得し、関連付けられた子エンティティと孫エンティティの一部にアクセスします。
Person
私がエンティティ を持っているとしましょう。- これ
Person
には関連付けられたAddress
エンティティがあります。- これ
Address
には関連付けられたCity
エンティティがあります。- この
City
エンティティにはname
プロパティがあります。
- この
- これ
- これ
person エンティティから始まる都市の名前にアクセスするためのフル パスは、次のようになります。
person.address.city.name
PersonService
ここで、このメソッドを使用して、から Person エンティティをロードするとします。
public Person findPersonById(long id)
{
// ...
}
Hibernate を使用すると、に関連付けられたエンティティPerson
をオンデマンドで遅延ロードできるためperson.address.city.name
、このプロパティにアクセスして、確実にアクセスできるようになります (そのチェーン内のすべてのエンティティが null 許容でない限り)。
しかし、私が調査している 3 つのソリューションのいずれかを使用すると、より複雑になります。これらのソリューションでは、このユース ケースを処理するために推奨されるパターンは何ですか? 前もって、3 つのパターンが考えられます。
必要なすべての関連付けられた子エンティティと孫エンティティは、使用された SQL クエリによって熱心に読み込まれます。
しかし、このソリューションで見られる問題は、エンティティから他のエンティティ/プロパティ パスにアクセスする必要がある他のコードが存在する可能性があること
Person
です。たとえば、一部のコードは へのアクセスが必要になる場合がありますperson.job.salary.currency
。既に持っているメソッドを再利用したい場合はfindPersonById()
、SQL クエリでさらに情報をロードする必要があります。address->city
関連エンティティだけでなく、関連エンティティもjob->salary
。person エンティティから始まる他の情報にアクセスする必要がある場所が他に10か所ある場合はどうなるでしょうか。潜在的に必要なすべての情報を常に熱心にロードする必要がありますか? または、個人エンティティをロードするために 12 の異なるサービス メソッドを使用することはありますか? :
findPersonById_simple(long id) findPersonById_withAdressCity(long id) findPersonById_withJob(long id) findPersonById_withAdressCityAndJob(long id) ...
しかし、
Person
エンティティを使用するたびに、何がロードされていて何がロードされていないかを知る必要があります...それはかなり面倒ですよね?エンティティの
getAddress()
getter メソッドでPerson
、アドレスが既に読み込まれているかどうかを確認し、読み込まれていない場合は遅延読み込みを行うことができますか? これは、実際のアプリケーションで頻繁に使用されるパターンですか?ロードされたモデルから必要なエンティティ/プロパティに確実にアクセスできるようにするために使用できる他のパターンはありますか?
ユース ケース 2 - エンティティを保存し、関連付けられたエンティティと変更されたエンティティも保存されることを確認します。
thisのメソッドPerson
を使用してエンティティを保存できるようにしたい:PersonService
public void savePerson(Person person)
{
// ...
}
Person
エンティティがあり、別のものに変更した場合、エンティティの変更が保存されてperson.address.city.name
いることを確認するにはどうすればよいですか? Hibernate を使用すると、保存操作を関連付けられたエンティティに簡単にカスケードできます。私が調査しているソリューションはどうですか?City
Person
人を保存するときに、関連付けられているエンティティも保存する必要があることを知るために、何らかのダーティフラグを使用する必要がありますか?
このユースケースに対処するのに役立つ既知のパターンは他にありますか?
更新:JOOQ フォーラムでこの質問についての議論があります。