HIBERNATE - Relational Persistence for Idiomatic Java
Hibernate Reference Documentation
Hibernateレファレンスドキュメンテーション
3.2.2
Table of Contents(コンテンツテーブル)
Preface(序文)
1. Introduction to Hibernate(Hibernateの紹介)
2. Architecture(アーキテクチャ)
3. Configuration(設定)
6. Collection Mapping(コレクションのマッピング)
7. Association Mappings(関連マッピング)
8. Component Mapping(コンポーネントのマッピング)
9. Inheritance Mapping(継承マッピング)
10. Working with objects(オブジェクトを扱う)
11. Transactions And Concurrency(トランザクションと並行性)
12. Interceptors and events(インターセプタとイベント)
13. Batch processing(バッチ処理)
15. Criteria Queries(Criteriaクエリ)
17. Filtering data(フィルタリングデータ)
19. Improving performance(パフォーマンスの改善)
20. Toolset Guide(ツールセットガイド)
21. Example: Parent/Child(例:親/子)
22. Example: Weblog Application(例:Weblogアプリケーション)
23. Example: Various Mappings(例:いろいろなマッピング)
Chapter 24. Best Practices(第24章:ベストプラクティス)
Write fine-grained classes and map them using <component>.(クラスは細かい粒度で書き <component> でマッピングしましょう。)
Use an Address class to encapsulate street, suburb, state, postcode. This encourages code reuse and simplifies refactoring.
street(通り), suburb(都市), state(州), postcode (郵便番号)をカプセル化するAddress(住所)クラスを使いましょう。そうすればコードが再利用しやすくなり、リファクタリングも簡単になります。
Declare identifier properties on persistent classes.( 永続クラスには識別子プロパティを定義しましょう。)
Hibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning).
Hibernateでは識別子プロパティはオプションですが、使用すべき理由がたくさんあります。識別子は「人工的」(生成された、業務的な意味を持たない)なものにすることをおすすめします。
Identify natural keys.( 自然キーを見つけましょう。)
Identify natural keys for all entities, and map them using <natural-id>. Implementequals() and hashCode() to compare the properties that make up the natural key.
すべてのエンティティに対して自然キーを見つけて、<natural-id> でマッピングしましょう。自然キーを構成するプロパティを比較するために、equals() と hashCode() を実装しましょう。
Place each class mapping in its own file.( クラスのマッピングはそれぞれのクラス専用のファイルに書きましょう。)
Don't use a single monolithic mapping document. Map com.eg.Foo in the filecom/eg/Foo.hbm.xml. This makes particularly good sense in a team environment.
単一の巨大なマッピングドキュメントを使用しないでください。com.eg.Foo クラスならcom/eg/Foo.hbm.xml ファイルにマッピングしましょう。このことは、特にチームでの開発に意味があります。
Load mappings as resources.( リソースとしてマッピングをロードしましょう。)
Deploy the mappings along with the classes they map.
マッピングを、それらがマッピングするするクラスと一緒に配置しましょう。
Consider externalising query strings.( クエリ文字列を外部に置くことを考えましょう)
This is a good practice if your queries call non-ANSI-standard SQL functions. Externalising the query strings to mapping files will make the application more portable.
クエリがANSI標準でないSQL関数を呼んでいるなら、これはよいプラクティスです。クエリ文字列をマッピングファイルへ外出しすればアプリケーションがポータブルになります。
Use bind variables.( バインド変数を使いましょう。)
As in JDBC, always replace non-constant values by "?". Never use string manipulation to bind a non-constant value in a query! Even better, consider using named parameters in queries.
JDBCの場合と同じように、定数でない値は必ず"?"で置き換えましょう。定数でない値をバインドするために、クエリで文字列操作を使ってはいけません。名前付きのパラメータを使うようにするとさらに良いです。
Don't manage your own JDBC connections.( JDBCコネクションを管理してはいけません。)
Hibernate lets the application manage JDBC connections. This approach should be considered a last-resort. If you can't use the built-in connections providers, consider providing your own implementation of org.hibernate.connection.ConnectionProvider.
HibernateではアプリケーションがJDBCコネクションを管理することが許されています。しかしこれは最終手段だと思ってください。組み込みのコネクションプロバイダを使うことができなければ、org.hibernate.connection.ConnectionProvider を実装することを考えてください。
Consider using a custom type.( カスタム型の使用を考えましょう。)
Suppose you have a Java type, say from some library, that needs to be persisted but doesn't provide the accessors needed to map it as a component. You should consider implementing org.hibernate.UserType. This approach frees the application code from implementing transformations to / from a Hibernate type.
あるライブラリから持ってきたJava型を永続化する必要があるとしましょう。しかしその型には、コンポーネントとしてマッピングするために必要なアクセサがないとします。このような場合は org.hibernate.UserType の実装を考えるべきです。そうすればHibernate型との実装変換を心配せずにアプリケーションのコードを扱えます。
Use hand-coded JDBC in bottlenecks.( ボトルネックを解消するにはJDBCをハンドコードしましょう。)
In performance-critical areas of the system, some kinds of operations might benefit from direct JDBC. But please, wait until you know something is a bottleneck. And don't assume that direct JDBC is necessarily faster. If you need to use direct JDBC, it might be worth opening a Hibernate Session and using that JDBC connection. That way you can still use the same transaction strategy and underlying connection provider.
システムのパフォーマンスクリティカルな領域では、ある種の操作にJDBCを直接使うと良いかもしれません。しかし何がボトルネックになっているか はっきりする までは待ってください。またJDBCを直接使うからといって、必ずしも速くなるとは限らないことも理解してください。JDBCを直接使う必要があれば、Hibernateの Session をオープンして、JDBCコネクションを使うと良いかもしれません。依然として同じトランザクション戦略とコネクションプロバイダが使えるからです。
Understand Session flushing.( Session のフラッシュを理解しましょう。)
From time to time the Session synchronizes its persistent state with the database. Performance will be affected if this process occurs too often. You may sometimes minimize unnecessary flushing by disabling automatic flushing or even by changing the order of queries and other operations within a particular transaction.
Sessionが永続状態をデータベースと同期させることがときどきあります。しかしこれがあまりに頻繁に起こるようだと、パフォーマンスに影響が出てきます。自動フラッシュを無効にしたり、特定のトランザクションのクエリや操作の順番を変更することで、不必要なフラッシュを最小限にできます。
In a three tiered architecture, consider using detached objects.( 3層アーキテクチャでは分離オブジェクトの使用を考えましょう。)
When using a servlet / session bean architecture, you could pass persistent objects loaded in the session bean to and from the servlet / JSP layer. Use a new session to service each request. Use Session.merge() or Session.saveOrUpdate() to synchronize objects with the database.
サーブレット / セッションビーンアーキテクチャを使うとき、サーブレット層 / JSP層間でセッションビーンでロードした永続オブジェクトをやり取りできます。その際リクエストごとに新しいSessionを使ってください。また Session.merge() やSession.saveOrUpdate() を使って、オブジェクトとデータベースを同期させてください。
In a two tiered architecture, consider using long persistence contexts.( 2層アーキテクチャでは長い永続コンテキストの使用を考えましょう。)
Database Transactions have to be as short as possible for best scalability. However, it is often neccessary to implement long running application transactions, a single unit-of-work from the point of view of a user. An application transaction might span several client request/response cycles. It is common to use detached objects to implement application transactions. An alternative, extremely appropriate in two tiered architecture, is to maintain a single open persistence contact (session) for the whole lifecycle of the application transaction and simply disconnect from the JDBC connection at the end of each request and reconnect at the beginning of the subsequent request. Never share a single session across more than one application transaction, or you will be working with stale data.
最高のスケーラビリティを得るには、データベーストランザクションをできるだけ短くしなければなりません。しかし長い間実行する アプリケーショントランザクション の実装が必要なことはしばしばです。これはユーザの視点からは1個の作業単位(unit of work)になります。アプリケーショントランザクションはいくつかのクライアントのリクエスト/レスポンスサイクルにまたがります。アプリケーショントランザクションの実装に分離オブジェクトを使うのは一般的です。そうでなければ、2層アーキテクチャの場合は特に適切なことですが、アプリケーショントランザクションのライフサイクル全体に対して単一のオープンな永続化コンテキスト(セッション)を維持してください。そして単純にリクエストの最後にJDBCコネクションから切断し、次のリクエストの最初に再接続します。決して複数のアプリケーショントランザクションユースケースに渡って1個のSessionを使い回さないでください。そうでなければ、古いデータで作業することになります。
Don't treat exceptions as recoverable.( 例外を復帰可能なものとして扱ってはいけません。)
This is more of a necessary practice than a "best" practice. When an exception occurs, roll back the Transaction and close the Session. If you don't, Hibernate can't guarantee that in-memory state accurately represents persistent state. As a special case of this, do not use Session.load() to determine if an instance with the given identifier exists on the database; use Session.get() or a query instead.
これは「ベスト」プラクティス以上の、必須のプラクティスです。例外が発生したときはTransaction をロールバックして、Session をクローズしてください。そうしないとHibernateはメモリの状態が永続状態を正確に表現していることを保証できません。この特別な場合として、与えられた識別子を持つインスタンスがデータベースに存在するかどうかを判定するために、Session.load() を使うことはやめてください。その代わりにSession.get() かクエリを使ってください。
Prefer lazy fetching for associations.( 関連にはなるべく遅延フェッチを使いましょう。)
Use eager fetching sparingly. Use proxies and lazy collections for most associations to classes that are not likely to be completely held in the second-level cache. For associations to cached classes, where there is an a extremely high probability of a cache hit, explicitly disable eager fetching using lazy="false". When an join fetching is appropriate to a particular use case, use a query with a left join fetch.
即時フェッチは控えめにしましょう。二次キャッシュには完全に保持されないようなクラスの関連には、プロキシと遅延コレクションを使ってください。キャッシュされるクラスの関連、つまりキャッシュがヒットする可能性が非常に高い関連は、lazy="false" で積極的なフェッチを明示的に無効にしてください。結合フェッチが適切な特定のユースケースには、クエリで left join fetch を使ってください。
Use the open session in view pattern, or a disciplined assembly phase to avoid problems with unfetched data. (フェッチされていないデータに関わる問題を避けるために、ビューの中でオープンセッションを使う(open session in view) パターンか、統制された 組み立てフェーズ(assembly phase) を使いましょう。)
Hibernate frees the developer from writing tedious Data Transfer Objects (DTO). In a traditional EJB architecture, DTOs serve dual purposes: first, they work around the problem that entity beans are not serializable; second, they implicitly define an assembly phase where all data to be used by the view is fetched and marshalled into the DTOs before returning control to the presentation tier. Hibernate eliminates the first purpose. However, you will still need an assembly phase (think of your business methods as having a strict contract with the presentation tier about what data is available in the detached objects) unless you are prepared to hold the persistence context (the session) open across the view rendering process. This is not a limitation of Hibernate! It is a fundamental requirement of safe transactional data access.
Hibernateは Data Transfer Objects (DTO)を書く退屈な作業から開発者を解放します。伝統的なEJBアーキテクチャではDTOは二つ目的があります:1つ目は、エンティティビーンがシリアライズされない問題への対策です。2つ目は、プレゼンテーション層に制御が戻る前に、ビューに使われるすべてのデータがフェッチされて、DTOに復元されるような組み立てフェーズを暗黙的に定義します。Hibernateでは1つ目の目的が不要になります。しかしビューのレンダリング処理の間、永続コンテキスト(セッション)をオープンにしたままにしなければ、組み立てフェーズはまだ必要です(分離オブジェクトの中のどのデータが利用可能かについて、プレゼンテーション層と厳密な取り決めをしているビジネスメソッドを考えてみてください)。これはHibernate側の問題ではありません。トランザクション内で安全にデータアクセスするための基本的な要件です。
Consider abstracting your business logic from Hibernate.( Hibernateからビジネスロジックを抽象化することを考えましょう。)
Hide (Hibernate) data-access code behind an interface. Combine the DAO and Thread Local Session patterns. You can even have some classes persisted by handcoded JDBC, associated to Hibernate via a UserType. (This advice is intended for "sufficiently large" applications; it is not appropriate for an application with five tables!)
インターフェイスで(Hibernateの)データアクセスコードを隠蔽しましょう。DAO とThread Local Session パターンを組み合わせましょう。UserType でHibernateに関連付けると、ハンドコードしたJDBCで永続化するクラスを持つこともできます。(このアドバイスは「十分大きな」アプリケーションに対してのものです。テーブルが5個しかないようなアプリケーションには当てはまりません。)
Don't use exotic association mappings.( 珍しい関連マッピングは使わないようにしましょう。)
Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.
よいユースケースに本当の多対多関連があることは稀(まれ)です。ほとんどの場合「リンクテーブル」の付加的な情報が必要になります。この場合、リンククラスに2つの1対多関連を使う方がずっと良いです。実際ほとんどの場合関連は1対多と多対1なので、他のスタイルの関連を使うときは本当に必要かどうかを考えてみてください。
Prefer bidirectional associations.( なるべく双方向関連にしましょう。)
Unidirectional associations are more difficult to query. In a large application, almost all associations must be navigable in both directions in queries.
単方向関連は双方向に比べて検索が難しくなります。大きなアプリケーションでは、ほとんどすべての関連が双方向にナビゲーションできなければなりません。
No comments:
Post a Comment