Sunday, May 25, 2008

HIBERNATE - Relational Persistence for Idiomatic Java - 19

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(設定)
4. Persistent Classes(永続クラス)
5. Basic O/R Mapping(基本的なO/Rマッピング)
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(バッチ処理)
14. HQL: The Hibernate Query Language(HQL:Hibernateクエリ言語)
15. Criteria Queries(Criteriaクエリ)
16. Native SQL(ネイティブSQL)
17. Filtering data(データのフィルタリング)
18. XML Mapping(XMLマッピング)
19. Improving performance(パフォーマンスの改善)
19.1. Fetching strategies(フェッチ戦略)
19.1.1. Working with lazy associations(遅延関連の働き)
19.1.2. Tuning fetch strategies(フェッチ戦略のチューニング)
19.1.3. Single-ended association proxies(単一端関連プロキシ)
19.1.4. Initializing collections and proxies(コレクションとプロキシの初期化)
19.1.5. Using batch fetching(バッチフェッチの使用)
19.1.6. Using subselect fetching(サブセレクトフェッチの使用)
19.1.7. Using lazy property fetching(遅延プロパティフェッチの使用)
19.2. The Second Level Cache(2次キャッシュ)
19.2.1. Cache mappings(キャッシュマッピング)
19.2.2. Strategy: read only(read only戦略)
19.2.3. Strategy: read/write(read/write戦略)
19.2.4. Strategy: nonstrict read/write(秘密ではないread/write戦略)
19.2.5. Strategy: transactional(Transactional)戦略
19.3. Managing the caches(キャッシュの管理)
19.4. The Query Cache(クエリキャッシュ)
19.5. Understanding Collection performance(コレクションのパフォーマンスの理解)
19.5.1. Taxonomy(分類)
19.5.2. Lists, maps, idbags and sets are the most efficient collections to update(更新にもっとも効率的なコレクション listmapidbagset)
19.5.3. Bags and lists are the most efficient inverse collections(inverseコレクションにもっとも最適なbaglist)
19.5.4. One shot delete(一括削除)
19.6. Monitoring performance(パフォーマンスのモニターリング)
19.6.1. Monitoring a SessionFactory(SessionFactoryのモニタリング)
19.6.2. Metrics(マトリックス)


Chapter 19. Improving performance(19章:パフォーマンスの改善)
19.1. Fetching strategies(フェッチ戦略)
fetching strategy is the strategy Hibernate will use for retrieving associated objects if the application needs to navigate the association. Fetch strategies may be declared in the O/R mapping metadata, or over-ridden by a particular HQL or Criteria query.
フェッチ戦略 は、アプリケーションが関連をナビゲートする必要があるときに、Hibernateが関連オブジェクトを復元するために使用する戦略です。フェッチ戦略はO/Rマッピングのメタデータに宣言するか、特定のHQL Criteria クエリでオーバーライドします。
Hibernate3 defines the following fetching strategies:
Hibernate3は次に示すフェッチ戦略を定義しています。
?         Join fetching - Hibernate retrieves the associated instance or collection in the same SELECT, using an OUTER JOIN.
結合フェッチ - Hibernate OUTER JOIN を使って、関連するインスタンスやコレクションを1つの SELECT で復元します。
?         Select fetching - a second SELECT is used to retrieve the associated entity or collection. Unless you explicitly disable lazy fetching by specifying lazy="false", this second select will only be executed when you actually access the association.
セレクトフェッチ - 2回目の SELECTで関連するエンティティやコレクションを復元します。 lazy="false" で明示的に遅延フェッチを無効にしなければ、この2回目のselectは実際に関連にアクセスしたときのみ実行されるでしょう。
?         Subselect fetching - a second SELECT is used to retrieve the associated collections for all entities retrieved in a previous query or fetch. Unless you explicitly disable lazy fetching by specifying lazy="false", this second select will only be executed when you actually access the association.
サブセレクトフェッチ - 2回目の SELECT で、直前のクエリやフェッチで復元したすべての要素に関連するコレクションを復元します。 lazy="false" で明示的に遅延フェッチを無効にしなければ、この2回目のselectは実際に関連にアクセスしたときのみ実行されるでしょう。
?         Batch fetching - an optimization strategy for select fetching - Hibernate retrieves a batch of entity instances or collections in a single SELECT, by specifying a list of primary keys or foreign keys.
バッチフェッチ - セレクトフェッチのための最適化された戦略 - Hibernateはエンティティのインスタンスやコレクションの一群を1回のSELECT で復元します。これは主キーや外部キーのリストを指定することにより行います。
Hibernate also distinguishes between:
Hibernateは次に示す戦略も区別します。
?         Immediate fetching - an association, collection or attribute is fetched immediately, when the owner is loaded.
即時フェッチ - 所有者のオブジェクトがロードされたときに、関連、コレクションは即時にフェッチされます。
?         Lazy collection fetching - a collection is fetched when the application invokes an operation upon that collection. (This is the default for collections.)
遅延コレクションフェッチ - アプリケーションがコレクションに対して操作を行ったときにコレクションをフェッチします。(これはコレクションに対するデフォルトの動作です)
?         "Extra-lazy" collection fetching - individual elements of the collection are accessed from the database as needed. Hibernate tries not to fetch the whole collection into memory unless absolutely needed (suitable for very large collections)
"特別な遅延"コレクションフェッチ - コレクションの要素1つ1つが独立して、必要なときにデータベースから取得されます。Hibernateは必要ないならば、コレクション全体をメモリにフェッチすることは避けます(とても大きなコレクションに適しています)。
?         Proxy fetching - a single-valued association is fetched when a method other than the identifier getter is invoked upon the associated object.
プロキシフェッチ - 単一値関連は、識別子のgetter以外のメソッドが関連オブジェクトで呼び出されるときにフェッチされます。
?         "No-proxy" fetching - a single-valued association is fetched when the instance variable is accessed. Compared to proxy fetching, this approach is less lazy (the association is fetched even when only the identifier is accessed) but more transparent, since no proxy is visible to the application. This approach requires buildtime bytecode instrumentation and is rarely necessary.
"プロキシなし"フェッチ - 単一値関連は、インスタンス変数にアクセスされたときにフェッチされます。プロキシフェッチと比較すると、この方法は遅延の度合いが少ない(関連は識別子にアクセスしただけでもフェッチされます)ですが、より透過的で、アプリケーションにプロキシが存在しないように見せます。この方法はビルド時のバイトコード組み込みが必要になり、使う場面はまれです。
?         Lazy attribute fetching - an attribute or single valued association is fetched when the instance variable is accessed. This approach requires buildtime bytecode instrumentation and is rarely necessary.
遅延属性フェッチ - 属性や単一値関連は、インスタンス変数にアクセスしたときにフェッチされます。この方法はビルド時のバイトコード組み込みが必要になり、使う場面はまれです。
We have two orthogonal notions here: when is the association fetched, and how is it fetched (what SQL is used). Don't confuse them! We use fetch to tune performance. We may use lazy to define a contract for what data is always available in any detached instance of a particular class.
二つの直行する概念がありますいつ 関連をフェッチするか、そして、 どうやって フェッチするか(どんなSQLを使って)。これらを混同しないでください! fetch はパフォーマンスチューニングに使います。lazy はあるクラスの分離されたインスタンスのうち、どのデータを常に使用可能にするかの取り決めを定義します。
19.1.1. Working with lazy associations(遅延関連の働き)
By default, Hibernate3 uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for almost all associations in almost all applications.
デフォルトでは、Hibernate3はコレクションに対しては遅延セレクトフェッチを使い、単一値関連には遅延プロキシフェッチを使います。これらのデフォルト動作はほぼすべてのアプリケーションのほぼすべての関連で意味があります。
Note: if you set hibernate.default_batch_fetch_size, Hibernate will use the batch fetch optimization for lazy fetching (this optimization may also be enabled at a more granular level).
:hibernate.default_batch_fetch_size をセットしたときは、Hibernateは遅延フェッチのためのバッチフェッチ最適化を使うでしょう(この最適化はより細かいレベルで有効にすることも出来ます)。
However, lazy fetching poses one problem that you must be aware of. Access to a lazy association outside of the context of an open Hibernate session will result in an exception. For example:
しかし、遅延フェッチは知っておかなければならない一つの問題があります。Hibernatesessionをオープンしているコンテキストの外から遅延関連にアクセスすると、例外が発生します。例:
s = sessions.openSession();
Transaction tx = s.beginTransaction();
            
User u = (User) s.createQuery("from User u where u.name=:userName")
    .setString("userName", userName).uniqueResult();
Map permissions = u.getPermissions();

tx.commit();
s.close();

Integer accessLevel = (Integer) permissions.get("accounts");  // Error!
Since the permissions collection was not initialized when the Session was closed, the collection will not be able to load its state. Hibernate does not support lazy initialization for detached objects. The fix is to move the code that reads from the collection to just before the transaction is committed.
Session がクローズされたとき、permissionsコレクションは初期化されていないため、このコレクションは自身の状態をロードできません。Hibernateは切り離されたオブジェクトの遅延初期化はサポートしていません 。修正方法として、コレクションから読み込みを行うコードをトランザクションをコミットする直前に移動させます。
Alternatively, we could use a non-lazy collection or association, by specifyinglazy="false" for the association mapping. However, it is intended that lazy initialization be used for almost all collections and associations. If you define too many non-lazy associations in your object model, Hibernate will end up needing to fetch the entire database into memory in every transaction!
一方で、 lazy="false" を関連マッピングに指定することで、遅延処理をしないコレクションや関連を使うことが出来ます。 しかしながら、遅延初期化はほぼすべてのコレクションや関連で使われることを意図しています。もしあなたのオブジェクトモデルの中に遅延処理をしない関連を多く定義してしまうと、Hibernateは最終的にはトランザクション毎にほぼ完全なデータベースをメモリの中にフェッチすることになるでしょう!
On the other hand, we often want to choose join fetching (which is non-lazy by nature) instead of select fetching in a particular transaction. We'll now see how to customize the fetching strategy. In Hibernate3, the mechanisms for choosing a fetch strategy are identical for single-valued associations and collections.
他方では、特定のトランザクションにおいてセレクトフェッチの代わりに結合フェッチ(当然これは遅延処理ではなくなります)を選択したいことが時々あります。これからフェッチ戦略をカスタマイズする方法をお見せします。Hibernate3では、フェッチ戦略を選択する仕組みは単一値関連とコレクションで変わりはありません。
19.1.2. Tuning fetch strategies(フェッチ戦略のチューニング)
Select fetching (the default) is extremely vulnerable to N+1 selects problems, so we might want to enable join fetching in the mapping document:
セレクトフェッチ(デフォルト)はN+1セレクト問題という大きな弱点があるため、マッピング定義で結合フェッチを有効にすることができます。
<set name="permissions" 
            fetch="join">
    <key column="userId"/>
    <one-to-many class="Permission"/>
</set
<many-to-one name="mother" class="Cat" fetch="join"/>
The fetch strategy defined in the mapping document affects:
マッピング定義で定義した フェッチ 戦略は次のものに影響します。
?         retrieval via get() or load() (get()  load() による復元)
?         retrieval that happens implicitly when an association is navigated (関連にナビゲートしたときに発生する暗黙的な復元)
?         Criteria queries (Criteriaクエリ)
?         HQL queries if subselect fetching is used (サブセレクト フェッチを使うHQLクエリ)
No matter what fetching strategy you use, the defined non-lazy graph is guaranteed to be loaded into memory. Note that this might result in several immediate selects being used to execute a particular HQL query.
たとえどんなフェッチ戦略を使ったとしても、遅延ではないグラフはメモリに読み込まれることが保証されます。つまり、特定のHQLクエリを実行するためにいくつかのSELECT文が即時実行されることがあるので注意してください。
Usually, we don't use the mapping document to customize fetching. Instead, we keep the default behavior, and override it for a particular transaction, using left join fetch in HQL. This tells Hibernate to fetch the association eagerly in the first select, using an outer join. In the Criteria query API, you would use setFetchMode(FetchMode.JOIN).
通常は、マッピング定義でフェッチのカスタマイズは行いません。代わりに、デフォルトの動作のままにしておいて、HQL left join fetch を指定することで特定のトランザクションで動作をオーバーライドします。これはHibernateに初回のセレクトで外部結合を使って関連を先にフェッチするように指定しています。Criteria クエリのAPIでは、setFetchMode(FetchMode.JOIN) を使うことが出来ます。
If you ever feel like you wish you could change the fetching strategy used by get() orload(), simply use a Criteria query, for example:
もし get()  load() で使われるフェッチ戦略を変えたいと感じたときには、単純にCriteria クエリを使ってください。例:
User user = (User) session.createCriteria(User.class)
                .setFetchMode("permissions", FetchMode.JOIN)
                .add( Restrictions.idEq(userId) )
                .uniqueResult();
(This is Hibernate's equivalent of what some ORM solutions call a "fetch plan".)
(これはいくつかのORMソリューションが"fetch plan"と呼んでいるものと同じです。)
A completely different way to avoid problems with N+1 selects is to use the second-level cache.
N+1セレクト問題を避けるためのまったく違う方法は、第2レベルキャッシュを使うことです。
19.1.3. Single-ended association proxies(単一端関連プロキシ)
Lazy fetching for collections is implemented using Hibernate's own implementation of persistent collections. However, a different mechanism is needed for lazy behavior in single-ended associations. The target entity of the association must be proxied. Hibernate implements lazy initializing proxies for persistent objects using runtime bytecode enhancement (via the excellent CGLIB library).
コレクションの遅延フェッチは、Hibernate自身の実装による永続コレクションを使って実現しています。しかし、単一端関連における遅延処理では、違う仕組みが必要です。対象の関連エンティティはプロキシでなければなりません。Hibernateは(すばらしいCGLIBライブラリによる)実行時のバイトコード拡張を使って永続オブジェクトの遅延初期化プロキシを実現しています。
By default, Hibernate3 generates proxies (at startup) for all persistent classes and uses them to enable lazy fetching of many-to-one and one-to-one associations.
デフォルトでは、Hibernate3は(開始時に)すべての永続クラスのプロキシを生成し、それらを使って、 many-to-one  one-to-one 関連の遅延フェッチを可能にしています。
The mapping file may declare an interface to use as the proxy interface for that class, with the proxy attribute. By default, Hibernate uses a subclass of the class. Note that the proxied class must implement a default constructor with at least package visibility. We recommend this constructor for all persistent classes!
マッピングファイルで proxy 属性によって、クラスのプロキシインターフェイスとして使うインターフェイスを宣言できます。デフォルトでは、Hibernateはそのクラスのサブクラスを使います。プロキシクラスは少なくともパッケージ可視でデフォルトコンストラクタを実装しなければならないことに注意してください。すべての永続クラスにこのコンストラクタを推奨します!
There are some gotchas to be aware of when extending this approach to polymorphic classes, eg.
ポリモーフィズムのクラスに対してこの方法を適用するときにいくつか考慮することがあります。例:
<class name="Cat" proxy="Cat">
    ......
    <subclass name="DomesticCat">
        .....
    </subclass>
</class>
Firstly, instances of Cat will never be castable to DomesticCat, even if the underlying instance is an instance of DomesticCat:
第一に、catのインスタンスはDomesticCatにキャッシュは出来ません。たとえ、基になるインスタンスがDomesticCatであったとしても。
Cat cat = (Cat) session.load(Cat.class, id);  // instantiate a proxy (does not hit the db)
if ( cat.isDomesticCat() ) {                  // hit the db to initialize the proxy
    DomesticCat dc = (DomesticCat) cat;       // Error!
    ....
}
Secondly, it is possible to break proxy ==.
第二に、プロキシの= =が成立しないことがあります。
Cat cat = (Cat) session.load(Cat.class, id);            // instantiate a Cat proxy
DomesticCat dc = 
        (DomesticCat) session.load(DomesticCat.class, id);  // acquire new DomesticCat proxy!
System.out.println(cat==dc);                            // false
However, the situation is not quite as bad as it looks. Even though we now have two references to different proxy objects, the underlying instance will still be the same object:
しかし、これは見かけほど悪い状況というわけではありません。たとえ異なったプロキシオブジェクトへの二つの参照があったとしても、基となるインスタンスは同じオブジェクトです。
cat.setWeight(11.0);  // hit the db to initialize the proxy
System.out.println( dc.getWeight() );  // 11.0
Third, you may not use a CGLIB proxy for a final class or a class with any final methods.
第三に、finalクラスはfinalメソッドを持つクラスにCGLIBプロキシを使用することが出来ません。
Finally, if your persistent object acquires any resources upon instantiation (eg. in initializers or default constructor), then those resources will also be acquired by the proxy. The proxy class is an actual subclass of the persistent class.
最後に、もし永続オブジェクトのインスタンス化時(例えば、初期化処理やデフォルトコンストラクタの中で)になんらかのリソースが必要となるなら、そのリソースもまたプロキシを通して取得されます。実際には、プロキシクラスは永続クラスのサブクラスです。
These problems are all due to fundamental limitations in Java's single inheritance model. If you wish to avoid these problems your persistent classes must each implement an interface that declares its business methods. You should specify these interfaces in the mapping file. eg.
これらの問題はJavaの単一継承モデルの原理上の制限のためです。もしこれらの問題を避けたいのなら、ビジネスメソッドを宣言したインターフェイスをそれぞれ永続クラスで実装しなければなりません。マッピングファイルでこれらのインターフェイスを指定する必要があります。例:
<class name="CatImpl" proxy="Cat">
    ......
    <subclass name="DomesticCatImpl" proxy="DomesticCat">
        .....
    </subclass>
</class>
where CatImpl implements the interface Cat and DomesticCatImpl implements the interface DomesticCat. Then proxies for instances of Cat and DomesticCat may be returned by load() or iterate(). (Note that list() does not usually return proxies.)
CatImpl  Cat インターフェイスを実装するのに対し、DomesticCatImpl  DomesticCatを実装します。すると、 load()  iterate() は、Cat  DomesticCat のインスタンスのプロキシを返します。( list() は通常はプロキシを返さないことに注意してください。)
Cat cat = (Cat) session.load(CatImpl.class, catid);
Iterator iter = session.iterate("from CatImpl as cat where cat.name='fritz'");
Cat fritz = (Cat) iter.next();
Relationships are also lazily initialized. This means you must declare any properties to be of type Cat, not CatImpl.
関連も遅延初期化されます。これはプロパティを Cat 型で宣言しなければならないことを意味します。 CatImpl ではありません。
Certain operations do not require proxy initialization
プロキシの初期化を 必要としない 操作も存在します。
?         equals(), if the persistent class does not override equals() (equals() (永続クラスが equals() をオーバーライドしないとき))
?         hashCode(), if the persistent class does not override hashCode() (hashCode() (永続クラスが hashCode() をオーバーライドしないとき))
?         The identifier getter method (識別子のgetterメソッド)
Hibernate will detect persistent classes that override equals() or hashCode().
Hibernate equals()  hashCode() をオーバーライドした永続クラスを検出します。
By choosing lazy="no-proxy" instead of the default lazy="proxy", we can avoid the problems associated with typecasting. However, we will require buildtime bytecode instrumentation, and all operations will result in immediate proxy initialization.
デフォルトの lazy="proxy" の代わりに、 lazy="no-proxy" を選んだことで、型変換に関連する問題を回避することが出来ます。しかし、ビルド時のバイトコード組み込みが必要になり、どのような操作であっても、ただちにプロキシの初期化を行うことになるでしょう。
19.1.4. Initializing collections and proxies(コレクションとプロキシの初期化)
LazyInitializationException will be thrown by Hibernate if an uninitialized collection or proxy is accessed outside of the scope of the Session, ie. when the entity owning the collection or having the reference to the proxy is in the detached state.
LazyInitializationException は、 Session のスコープ外から初期化していないコレクションやプロキシにアクセスされたときに、Hibernateによってスローされます。すなわち、コレクションやプロキシへの参照を持つエンティティが分離された状態の時です。
Sometimes we need to ensure that a proxy or collection is initialized before closing theSession. Of course, we can alway force initialization by calling cat.getSex() orcat.getKittens().size(), for example. But that is confusing to readers of the code and is not convenient for generic code.
Session をクローズする前にプロキシやコレクションの初期化を確実に行いたいときがあります。もちろん、 cat.getSex()  cat.getKittens().size() などを常に呼び出すことで初期化を強制することはできます。しかしこれはコードを読む人を混乱させ、汎用的なコードという点からも不便です。
The static methods Hibernate.initialize() and Hibernate.isInitialized() provide the application with a convenient way of working with lazily initialized collections or proxies. Hibernate.initialize(cat) will force the initialization of a proxy, cat, as long as its Session is still open. Hibernate.initialize( cat.getKittens() ) has a similar effect for the collection of kittens.
staticメソッドの Hibernate.initialize()  Hibernate.isInitialized() は遅延初期化のコレクションやプロキシを扱うときに便利な方法をアプリケーションに提供します。Hibernate.initialize(cat) は、 Session がオープンしている限りはcat プロキシを強制的に初期化します。Hibernate.initialize( cat.getKittens() ) kittensコレクションに対して同様の効果があります。
Another option is to keep the Session open until all needed collections and proxies have been loaded. In some application architectures, particularly where the code that accesses data using Hibernate, and the code that uses it are in different application layers or different physical processes, it can be a problem to ensure that the Session is open when a collection is initialized. There are two basic ways to deal with this issue:
別の選択肢として、必要なすべてのコレクションやプロキシがロードされるまでSessionをオープンにしておく方法があります。いくつかのアプリケーションのアーキテクチャでは、特にHibernateによるデータアクセスを行うコードと、それを使うコードが異なるアプリケーションのレイヤーや、物理的に異なるプロセッサのときには、コレクションが初期化されるときに Session がオープンしていることを保証する問題があります。この問題に対しては2つの基本的な方法があります。
?         In a web-based application, a servlet filter can be used to close the Session only at the very end of a user request, once the rendering of the view is complete (the Open Session in View pattern). Of course, this places heavy demands on the correctness of the exception handling of your application infrastructure. It is vitally important that theSession is closed and the transaction ended before returning to the user, even when an exception occurs during rendering of the view. See the Hibernate Wiki for examples of this "Open Session in View" pattern.
Webベースのアプリケーションでは、ビューのレンダリングが完了し、リクエストが終わる一番最後で Session をクローズするために、サーブレットフィルタを使うことができます( Open Session in View パターンです)。もちろん、アプリケーション基盤の例外処理の正確性が非常に重要になります。ビューのレンダリング中に例外が発生したときでさえ、ユーザに処理が戻る前にSession のクローズとトランザクションの終了を行うことが不可欠になります。HibernateWikiに載っている"Open Session in View"パターンの例を参照してください。
?         In an application with a separate business tier, the business logic must "prepare" all collections that will be needed by the web tier before returning. This means that the business tier should load all the data and return all the data already initialized to the presentation/web tier that is required for a particular use case. Usually, the application calls Hibernate.initialize() for each collection that will be needed in the web tier (this call must occur before the session is closed) or retrieves the collection eagerly using a Hibernate query with a FETCH clause or a FetchMode.JOIN in Criteria. This is usually easier if you adopt the Command pattern instead of a Session Facade.
ビジネス層が分離しているアプリケーションでは、ビジネスロジックはWeb層で必要になるすべてのコレクションを事前に"準備"する必要があります。これは特定のユースケースで必要となるプレゼンテーション/Web層に対し、ビジネス層がすべてのデータをロードし、すべてのデータを初期化して返すべきということを意味しています。通常は、アプリケーションはWeb層で必要なコレクションそれぞれに対して Hibernate.initialize() を呼び出すか(この呼び出しはセッションをクローズする前に行う必要があります)、Hibernateクエリの FETCH 節や Criteria  FetchMode.JOIN を使ってコレクションを先に復元します。普通は Session Facade パターンの代わりにCommand パターンを採用するほうがより簡単です。
?         You may also attach a previously loaded object to a new Session with merge() orlock() before accessing uninitialized collections (or other proxies). No, Hibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!
初期化されていないコレクション(もしくは他のプロキシ)にアクセスする前に、merge()  lock() を使って新しいSession に以前にロードされたオブジェクトを追加することも出来ます。アドホックなトランザクションのセマンティクスを導入したので、Hibernateはこれを自動的に行わず、 行うべきでもありません 
Sometimes you don't want to initialize a large collection, but still need some information about it (like its size) or a subset of the data.
大きなコレクションを初期化したくはないが、コレクションについてのなんらかの情報(サイズのような)やデータのサブセットを必要とすることがあります。
You can use a collection filter to get the size of a collection without initializing it:
コレクションフィルタを使うことで、初期化せずにコレクションのサイズを取得することが出来ます。
( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()
The createFilter() method is also used to efficiently retrieve subsets of a collection without needing to initialize the whole collection:
createFilter()メソッドは、コレクション全体を初期化することなく、コレクションのサブセットを復元するために効果的に使えます。
s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();
19.1.5. Using batch fetching(バッチフェッチの使用)
Hibernate can make efficient use of batch fetching, that is, Hibernate can load several uninitialized proxies if one proxy is accessed (or collections. Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level.
Hibernateはバッチフェッチを効率的にしよう出来ます。一つのプロキシ(もしくはコレクション)がアクセスされると、Hibernateはいくつかの初期化していないプロキシをロードすることが出来ます。バッチフェッチは遅延セレクトフェッチ戦略に対する最適化です。バッチフェッチの調整には2つの方法があります。クラスレベルとコレクションレベルです。
Batch fetching for classes/entities is easier to understand. Imagine you have the following situation at runtime: You have 25 Cat instances loaded in a Session, each Cathas a reference to its owner, a Person. The Person class is mapped with a proxy,lazy="true". If you now iterate through all cats and call getOwner() on each, Hibernate will by default execute 25 SELECT statements, to retrieve the proxied owners. You can tune this behavior by specifying a batch-size in the mapping of Person:
クラス、要素のバッチフェッチ理解することは簡単です。実行時の次の場面を想像してください。Sessionにロードされた25個のCatインスタンスが存在し、それぞれのCatownerであるPersonへの関連を待ちます。Personクラスはlazy="true"のプロキシでマッピングされています。もし今すべてのCatに対して繰り返しgetOwner()を呼び出すと、Hibernateはデフォルトでは25個のSELECTを実行し、ownerプロキシの復元をします。この振る舞いをPersonのマッピングのbatch-sizeの指定で調整できます。
<class name="Person" batch-size="10">...</class>
Hibernate will now execute only three queries, the pattern is 10, 10, 5.
Hibernateはクエリを3回だけを実行するようになります。パターンは10, 10, 5です。
You may also enable batch fetching of collections. For example, if each Person has a lazy collection of Cats, and 10 persons are currently loaded in the Sesssion, iterating through all persons will generate 10 SELECTs, one for every call to getCats(). If you enable batch fetching for the cats collection in the mapping of Person, Hibernate can pre-fetch collections:
コレクションのバッチフェッチも有効にすることが出来ます。例として、それぞれのPerson  Cat の遅延コレクションを持っており、10個のPerson Sesssion にロードされたとすると、すべてのPersonに対して繰り返し getCats() を呼び出すことで、計10回のSELECT が発生します。もし Person のマッピングで cats コレクションのバッチフェッチを有効にすれば、Hibernateはコレクションの事前フェッチが出来ます。
<class name="Person">
    <set name="cats" batch-size="3">
        ...
    </set>
</class>
With a batch-size of 8, Hibernate will load 3, 3, 3, 1 collections in four SELECTs. Again, the value of the attribute depends on the expected number of uninitialized collections in a particular Session.
batch-size 8なので、Hibernate4回の SELECT 3331をロードします。繰り返すと、属性の値は特定の Session の中の初期化されていないコレクションの期待数に依存します。
Batch fetching of collections is particularly useful if you have a nested tree of items, ie. the typical bill-of-materials pattern. (Although a nested set or a materialized pathmight be a better option for read-mostly trees.)
コレクションのバッチフェッチはアイテムのネストしたツリー、 すなわち、代表的な部品表のパターンがある場合に特に有用です。(しかし、読み込みが多いツリーでは ネストしたset  具体化したパス がよりよい選択になります。)
19.1.6. Using subselect fetching(サブセレクトフェッチの使用)
If one lazy collection or single-valued proxy has to be fetched, Hibernate loads all of them, re-running the original query in a subselect. This works in the same way as batch-fetching, without the piecemeal loading.
一つの遅延コレクションや単一値プロキシがフェッチされなければいけないとき、Hibernateはそれらすべてをロードし、サブセレクトのオリジナルクエリが再度実行されます。これはバッチフェッチと同じ方法で働き、少しずつのロードは行いません。
19.1.7. Using lazy property fetching(遅延プロパティフェッチの使用)
Hibernate3 supports the lazy fetching of individual properties. This optimization technique is also known as fetch groups. Please note that this is mostly a marketing feature, as in practice, optimizing row reads is much more important than optimization of column reads. However, only loading some properties of a class might be useful in extreme cases, when legacy tables have hundreds of columns and the data model can not be improved.
Hibernate3はプロパティごとの遅延フェッチをサポートしています。この最適化手法はグループのフェッチ としても知られています。これはほとんど要望から出た機能であることに注意してください。実際には列読み込みの最適化よりも、行読み込みの最適化が非常に重要です。しかし、クラスのいくつかのプロパティだけを読み込むことは、既存のテーブルが何百もの列を持ち、データモデルを改善できないなどの極端な場合には有用です。
To enable lazy property loading, set the lazy attribute on your particular property mappings:
遅延プロパティ読み込みを有効にするには、対象のプロパティのマッピングで lazy 属性をセットしてください。
<class name="Document">
       <id name="id">
        <generator class="native"/>
    </id>
    <property name="name" not-null="true" length="50"/>
    <property name="summary" not-null="true" length="200" lazy="true"/>
    <property name="text" not-null="true" length="2000" lazy="true"/>
</class>
Lazy property loading requires buildtime bytecode instrumentation! If your persistent classes are not enhanced, Hibernate will silently ignore lazy property settings and fall back to immediate fetching.
遅延プロパティ読み込みはビルド時のバイトコード組み込みを必要とします!もし永続クラスに組み込みがされていないなら、Hibernateは黙って遅延プロパティの設定を無視して、即時フェッチに戻します。
For bytecode instrumentation, use the following Ant task:
バイトコード組み込みは以下のAntタスクを使ってください。
<target name="instrument" depends="compile">
    <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
        <classpath path="${jar.path}"/>
        <classpath path="${classes.dir}"/>
        <classpath refid="lib.class.path"/>
    </taskdef>

    <instrument verbose="true">
        <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
            <include name="*.class"/>
        </fileset>
    </instrument>
</target>
A different (better?) way to avoid unnecessary column reads, at least for read-only transactions is to use the projection features of HQL or Criteria queries. This avoids the need for buildtime bytecode processing and is certainly a prefered solution.
不要な列を読み込まないための、別の(よりよい?)方法は、少なくとも読み込みのみのトランザクションにおいては、HQLCriteriaクエリの射影機能を使うことです。この方法はビルド時のバイトコード組み込みが不要になり、より良い解決方法です。
You may force the usual eager fetching of properties using fetch all properties in HQL.
HQL fetch all properties を使うことで、普通どおりのプロパティの即時フェッチングを強制することが出来ます。
19.2. The Second Level Cache(二次キャッシュ)
A Hibernate Session is a transaction-level cache of persistent data. It is possible to configure a cluster or JVM-level (SessionFactory-level) cache on a class-by-class and collection-by-collection basis. You may even plug in a clustered cache. Be careful. Caches are never aware of changes made to the persistent store by another application (though they may be configured to regularly expire cached data).
Hibernate Session は永続データのトランザクションレベルのキャッシュです。class-by-classcollection-by-collectionごとの、クラスタレベルやJVMレベル( SessionFactoryレベル)のキャッシュを設定することが出来ます。クラスタ化されたキャッシュにつなぐことさえ出来ます。しかし注意してください。キャッシュは他のアプリケーションによる永続層の変更を考慮しません(キャッシュデータを定期的に期限切れにする設定は出来ます)。
You have the option to tell Hibernate which caching implementation to use by specifying the name of a class that implements org.hibernate.cache.CacheProvider using the property hibernate.cache.provider_class. Hibernate comes bundled with a number of built-in integrations with open-source cache providers (listed below); additionally, you could implement your own and plug it in as outlined above. Note that versions prior to 3.2 defaulted to use EhCache as the default cache provider; that is no longer the case as of 3.2.
Hibernateが使用するキャッシュ実装は、hibernate.cache.provider_class プロパティにorg.hibernate.cache.CacheProvider を実装したクラス名を指定することで変更できます。Hibernateは多くのオープンソースのキャッシュプロバイダをビルトイン実装で持っています(後にリストがあります)。加えて、前に説明したように、あなた自身が独自の実装をして、それを組み込むことも出来ます。バージョン3.2より前ではEhCacheがデフォルトのキャッシュプロバイダであることに注意してください。バージョン3.2ではこれは当てはまりません。
Table 19.1. Cache Providers(キャッシュプロバイダ)
Cache(キャッシュ)
Provider class(プロバイダクラス)
Type()
Cluster Safe(クラスタセーフ)
Query Cache Supported(クエリキャッシュのサポート)
Hashtable (not intended for production use)
org.hibernate.cache.HashtableCacheProvider
memory

yes
EHCache
org.hibernate.cache.EhCacheProvider
memory, disk

yes
OSCache
org.hibernate.cache.OSCacheProvider
memory, disk

yes
SwarmCache
org.hibernate.cache.SwarmCacheProvider
clustered (ip multicast)
yes (clustered invalidation)

JBoss TreeCache
org.hibernate.cache.TreeCacheProvider
clustered (ip multicast), transactional
yes (replication)
yes (clock sync req.)
19.2.1. Cache mappings(キャッシュマッピング)
The <cache> element of a class or collection mapping has the following form:
クラスやコレクションのマッピングの <cache> 要素は以下の形式です。
<cache 
    usage="transactional|read-write|nonstrict-read-write|read-only"  (1)
    region="RegionName"                                              (2)
    include="all|non-lazy"                                           (3)
/>
(1)
usage (required)(必須) specifies the caching strategy: transactionalread-write,nonstrict-read-write or read-only
(2)
region (optional, defaults to the class or collection role name)(オプション、 - デフォルトは) specifies the name of the second level cache region
(3)
include (optional, defaults to all) (オプション、 - デフォルトはall) non-lazy specifies that properties of the entity mapped with lazy="true" may not be cached when attribute-level lazy fetching is enabled
Alternatively (preferrably?), you may specify <class-cache> and <collection-cache>elements in hibernate.cfg.xml.
または(よりよい方法として?)、 hibernate.cfg.xml  <class-cache>  <collection-cache> 要素を指定することも出来ます。
The usage attribute specifies a cache concurrency strategy.
usage 属性は キャッシュの並列性戦略 を指定します。
19.2.2. Strategy: read only(read only戦略)
If your application needs to read but never modify instances of a persistent class, a read-only cache may be used. This is the simplest and best performing strategy. It's even perfectly safe for use in a cluster.
もしアプリケーションが読み込みのみ必要で、永続クラスのインスタンスを変更しないなら、read-only キャッシュを使うことが出来ます。これはもっとも単純でもっともパフォーマンスの良い戦略です。クラスタでの使用も完全に安全です。
<class name="eg.Immutable" mutable="false">
    <cache usage="read-only"/>
    ....
</class>
19.2.3. Strategy: read/write(read/write戦略)
If the application needs to update data, a read-write cache might be appropriate. This cache strategy should never be used if serializable transaction isolation level is required. If the cache is used in a JTA environment, you must specify the propertyhibernate.transaction.manager_lookup_class, naming a strategy for obtaining the JTATransactionManager. In other environments, you should ensure that the transaction is completed when Session.close() or Session.disconnect() is called. If you wish to use this strategy in a cluster, you should ensure that the underlying cache implementation supports locking. The built-in cache providers do not.
アプリケーションがデータを更新する必要があるなら、 read-write キャッシュが適当かもしれません。このキャッシュ戦略は、シリアライザブルなトランザクション分離レベルが要求されるなら、決して使うべきではありません。もしキャッシュがJTA環境で使われるなら、JTA TransactionManager を取得するための方法を示すhibernate.transaction.manager_lookup_class プロパティを指定しなければなりません。他の環境では、 Session.close()  Session.disconnect() が呼ばれたときに、確実にトランザクションが完了していなければなりません。もしクラスタでこの戦略を使いたいなら、基となるキャッシュの実装がロックをサポートしていることを保証しなければなりません。組み込みのキャッシュプロバイダは サポートしていません 
<class name="eg.Cat" .... >
    <cache usage="read-write"/>
    ....
    <set name="kittens" ... >
        <cache usage="read-write"/>
        ....
    </set>
</class>
19.2.4. Strategy: nonstrict read/write(秘密ではないread/write戦略)
If the application only occasionally needs to update data (ie. if it is extremely unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate. If the cache is used in a JTA environment, you must specifyhibernate.transaction.manager_lookup_class. In other environments, you should ensure that the transaction is completed when Session.close() or Session.disconnect() is called.
アプリケーションがたまにしかデータを更新する必要はなく(すなわち二つのトランザクションが同時に同じアイテムを更新しようとすることはほとんど起こらない)、厳密なトランザクション分離が要求されないなら、 nonstrict-read-write キャッシュが適当かもしれません。もしキャッシュがJTA環境で使われるなら、hibernate.transaction.manager_lookup_class を指定しなければなりません。他の環境では、 Session.close()  Session.disconnect() が呼ばれたときに、確実にトランザクションが完了していなければなりません。
19.2.5. Strategy: transactional(transactional戦略)
The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must specify hibernate.transaction.manager_lookup_class.
transactional キャッシュ戦略はJBoss TreeCacheのような完全なトランザクショナルキャッシュプロバイダのサポートを提供します。このようなキャッシュはJTA環境でのみ使用可能で、 hibernate.transaction.manager_lookup_class を指定しなければなりません。
None of the cache providers support all of the cache concurrency strategies. The following table shows which providers are compatible with which concurrency strategies.
すべての同時並行性キャッシュ戦略をサポートしているキャッシュプロバイダはありません。以下の表はどのプロバイダがどの同時並列性戦略に対応するかを表しています。
Table 19.2. Cache Concurrency Strategy Support(同時並行性キャッシュ戦略のサポート)
Cache
read-only
nonstrict-read-write
read-write
transactional
Hashtable (not intended for production use)
yes
yes
yes

EHCache
yes
yes
yes

OSCache
yes
yes
yes

SwarmCache
yes
yes


JBoss TreeCache
yes


yes
19.3. Managing the caches(キャッシュの管理)
Whenever you pass an object to save()update() or saveOrUpdate() and whenever you retrieve an object using load()get()list()iterate() or scroll(), that object is added to the internal cache of the Session.
オブジェクトを save()  update()  saveOrUpdate() に渡すとき、そして load() get()  list() iterate()  scroll() を使ってオブジェクトを復元するときには常に、そのオブジェクトは Session の内部キャッシュに追加されます。
When flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur or if you are processing a huge number of objects and need to manage memory efficiently, the evict() method may be used to remove the object and its collections from the first-level cache.
次に flush() が呼ばれると、オブジェクトの状態はデータベースと同期化されます。もしこの同期が起こることを望まないときや、膨大な数のオブジェクトを処理していてメモリを効率的に扱う必要があるときは、 evict() メソッドを使って一次キャッシュからオブジェクトやコレクションを削除することが出来ます。
ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
    Cat cat = (Cat) cats.get(0);
    doSomethingWithACat(cat);
    sess.evict(cat);
}
The Session also provides a contains() method to determine if an instance belongs to the session cache.
Session はインスタンスがセッションキャッシュに含まれるかどうかを判断するためのcontains() メソッドも提供します。
To completely evict all objects from the session cache, call Session.clear()
すべてのオブジェクトをセッションキャッシュから完全に取り除くには、Session.clear()を呼び出してください。
For the second-level cache, there are methods defined on SessionFactory for evicting the cached state of an instance, entire class, collection instance or entire collection role.
二次キャッシュのために、 SessionFactory にはインスタンス、クラス全体、コレクションのインスタンス、コレクション全体をキャッシュから削除するためのメソッドがそれぞれ定義されています。
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
The CacheMode controls how a particular session interacts with the second-level cache.
CacheMode は特定のセッションが二次キャッシュとどのように相互作用するかを指定します。
?         CacheMode.NORMAL - read items from and write items to the second-level cache
CacheMode.NORMAL - アイテムの読み込みと書き込みで二次キャッシュを使います
?         CacheMode.GET - read items from the second-level cache, but don't write to the second-level cache except when updating data
CacheMode.GET - 読み込みは二次キャッシュから行いますが、データを更新した場合を除いて二次キャッシュに書き込みをしません。
?         CacheMode.PUT - write items to the second-level cache, but don't read from the second-level cache
CacheMode.PUT - 二次キャッシュにアイテムを書き込みますが、読み込みには二次キャッシュを使いません。
?         CacheMode.REFRESH - write items to the second-level cache, but don't read from the second-level cache, bypass the effect of hibernate.cache.use_minimal_puts, forcing a refresh of the second-level cache for all items read from the database
CacheMode.REFRESH - 二次キャッシュにアイテムを書き込みますが、読み込みには二次キャッシュを使わず、 hibernate.cache.use_minimal_puts の影響を受けずに、データベースから読み込むすべてのアイテムの二次キャッシュを強制的にリフレッシュします。
To browse the contents of a second-level or query cache region, use the Statistics API:
二次キャッシュの内容やクエリキャッシュ領域を見るために、 Statistics APIを使ってください。
Map cacheEntries = sessionFactory.getStatistics()
        .getSecondLevelCacheStatistics(regionName)
        .getEntries();
You'll need to enable statistics, and, optionally, force Hibernate to keep the cache entries in a more human-understandable format:
統計情報を有効にして、さらにオプションとして、キャッシュエントリを人がより理解可能な形式で保持することをHibernateに強制します。
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true
19.4. The Query Cache(クエリキャッシュ)
Query result sets may also be cached. This is only useful for queries that are run frequently with the same parameters. To use the query cache you must first enable it:
クエリのリザルトセットもキャッシュ出来ます。これは同じパラメータで何度も実行されるクエリに対してのみ有用です。クエリキャッシュを使うには、まず設定で有効にしなくてはなりません。
hibernate.cache.use_query_cache true
This setting causes the creation of two new cache regions - one holding cached query result sets (org.hibernate.cache.StandardQueryCache), the other holding timestamps of the most recent updates to queryable tables (org.hibernate.cache.UpdateTimestampsCache). Note that the query cache does not cache the state of the actual entities in the result set; it caches only identifier values and results of value type. So the query cache should always be used in conjunction with the second-level cache.
この設定は新たに二つのキャッシュ領域の作成を行います。一つはクエリのリザルトセットのキャッシュ( org.hibernate.cache.StandardQueryCache )を保持し、もう1つはクエリ可能なテーブルへの最新の更新タイムスタンプ(org.hibernate.cache.UpdateTimestampsCache )を保持します。クエリキャッシュはリザルトセットの実際の要素の状態はキャッシュしないことに注意してください。キャッシュするのは識別子の値と、値型の結果のみです。そのため、クエリキャッシュは常に二次キャッシュと一緒に使うべきです。
Most queries do not benefit from caching, so by default queries are not cached. To enable caching, call Query.setCacheable(true). This call allows the query to look for existing cache results or add its results to the cache when it is executed.
ほとんどのクエリはキャッシュの恩恵を受けないので、デフォルトではクエリはキャッシュされません。キャッシュを有効にするには、Query.setCacheable(true) を呼び出してください。そうすればクエリが既存のキャッシュ結果を探し、クエリ実行時にその結果をキャッシュに追加するようになります。
If you require fine-grained control over query cache expiration policies, you may specify a named cache region for a particular query by calling Query.setCacheRegion().
クエリキャッシュの破棄ポリシーを細かく制御したいときは、 Query.setCacheRegion()を呼び出して特定のクエリに対するキャッシュ領域を指定することが出来ます。
List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
    .setEntity("blogger", blogger)
    .setMaxResults(15)
    .setCacheable(true)
    .setCacheRegion("frontpages")
    .list();
If the query should force a refresh of its query cache region, you should callQuery.setCacheMode(CacheMode.REFRESH). This is particularly useful in cases where underlying data may have been updated via a separate process (i.e., not modified through Hibernate) and allows the application to selectively refresh particular query result sets. This is a more efficient alternative to eviction of a query cache region viaSessionFactory.evictQueries().
クエリが自身のクエリキャッシュ領域のリフレッシュを強制しなければならないなら、Query.setCacheMode(CacheMode.REFRESH) を呼び出すべきです。これは元となるデータが別のプロセスによって更新されたり(すなわちHibernateを通じて更新されない)、アプリケーションに特定のクエリリザルトセットを選択してリフレッシュさせる場合に特に有用です。さらに有用なもう一つの方法は、 SessionFactory.evictQueries() によってクエリキャッシュ領域を消去することです。
19.5. Understanding Collection performance(コレクションのパフォーマンスの理解)
We've already spent quite some time talking about collections. In this section we will highlight a couple more issues about how collections behave at runtime.
コレクションの話題にはすでに多くの時間を使いました。この節ではコレクションが実行時にどのように振舞うかについての話題を23取り上げます。
19.5.1. Taxonomy(分類)
Hibernate defines three basic kinds of collections:
Hibernate3つの基本的なコレクションの種類を定義しています。
?         collections of values(値のコレクション)
?         one to many associations(一対多関連)
?         many to many associations(多対多関連)
This classification distinguishes the various table and foreign key relationships but does not tell us quite everything we need to know about the relational model. To fully understand the relational structure and performance characteristics, we must also consider the structure of the primary key that is used by Hibernate to update or delete collection rows. This suggests the following classification:
この分類はさまざまなテーブルや外部キー関連を区別しますが、私たちが知る必要のある関連モデルについてほとんどなにも教えてくれません。関連構造やパフォーマンスの特徴を完全に理解するには、Hibernateがコレクションの行を更新、削除するために使う主キーの構造もまた考えなければなりません。これは以下の分類を提示します。
?         indexed collections(インデックス付コレクション)
?         sets
?         bags
All indexed collections (maps, lists, arrays) have a primary key consisting of the <key>and <index> columns. In this case collection updates are usually extremely efficient - the primary key may be efficiently indexed and a particular row may be efficiently located when Hibernate tries to update or delete it.
すべてのインデックス付きコレクション(maplist、配列)は <key>  <index> カラムからなる主キーを持っています。この場合はコレクションの更新は非常に効率的です。主キーは有用なインデックスになり、Hibernateが特定の行を更新または削除するときに、その行を効率的に見つけることができます。
Sets have a primary key consisting of <key> and element columns. This may be less efficient for some types of collection element, particularly composite elements or large text or binary fields; the database may not be able to index a complex primary key as efficently. On the other hand, for one to many or many to many associations, particularly in the case of synthetic identifiers, it is likely to be just as efficient. (Side-note: if you want SchemaExport to actually create the primary key of a <set> for you, you must declare all columns as not-null="true".)
set <key> からなる主キーと要素のカラムを持っています。これはコレクション要素のいくつかの型については効率的ではないかもしれません。特に複合要素、大きなテキスト、バイナリフィールドでは非効率です。データベースは複合主キーに効率的にインデックスを付けることができないからです。一方、1対多や多対多関連において、特に人工識別子の場合は同じぐらい効率的です。(余談: SchemaExport で実際に <set> の主キーを作りたいなら、すべてのカラムでnot-null="true" を宣言しなければなりません。)
<idbag> mappings define a surrogate key, so they are always very efficient to update. In fact, they are the best case.
<idbag> マッピングは代理キーを定義します。そのため更新は常に非常に効率的です。事実上、これは最善のケースです。
Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. Hibernate has no way of distinguishing between duplicate rows. Hibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. This might be very inefficient.
bagは最悪のケースです。bagは要素の値の重複が可能で、インデックスカラムを持たないため、主キーは定義されないかもしれません。Hibernateには重複した行を区別する方法がありません。Hibernateはこの問題の解決のために、変更があったときには常に完全な削除(一つの DELETE による)を行い、コレクションの再作成を行います。これは非常に非効率的かもしれません。
Note that for a one-to-many association, the "primary key" may not be the physical primary key of the database table - but even in this case, the above classification is still useful. (It still reflects how Hibernate "locates" individual rows of the collection.)
一対多関連では、「主キー」はデータベースのテーブルの物理的な主キーではないかもしれないことに注意してください。しかしこの場合でさえ、上記の分類はまだ有用です。(Hibernateがコレクションの個々の行をどうやって「見つけるか」を表しています。)
19.5.2. Lists, maps, idbags and sets are the most efficient collections to update(更新にもっとも効率的なコレクション listmapidbagset)
From the discussion above, it should be clear that indexed collections and (usually) sets allow the most efficient operation in terms of adding, removing and updating elements.
上での議論から、インデックス付きコレクションと(普通の)setは要素の追加、削除、更新でもっとも効率的な操作が出来ることは明らかです。
There is, arguably, one more advantage that indexed collections have over sets for many to many associations or collections of values. Because of the structure of a Set, Hibernate doesn't ever UPDATE a row when an element is "changed". Changes to a Setalways work via INSERT and DELETE (of individual rows). Once again, this consideration does not apply to one to many associations.
多対多関連や値のコレクションにおいて、インデックス付きコレクションがsetよりも優れている点が一つ以上あります。 Set はその構造のために、Hibernateは要素が「変更」されたときに行を決して UPDATE しません。 Set への変更は常に(個々の行の)INSERT DELETE によって行います。繰り返しますが、これは一対多関連には当てはまりません。
After observing that arrays cannot be lazy, we would conclude that lists, maps and idbags are the most performant (non-inverse) collection types, with sets not far behind. Sets are expected to be the most common kind of collection in Hibernate applications. This is because the "set" semantics are most natural in the relational model.
配列は遅延処理ができないという決まりなので、結論として、listmapidbagがもっともパフォーマンスの良い(inverseではない)コレクションタイプとなります。setもそれほど違いはありません。Hibernateのアプリケーションでは、setはコレクションのもっとも共通の種類として期待されます。setの表現は関連モデルではもっとも自然だからです。
However, in well-designed Hibernate domain models, we usually see that most collections are in fact one-to-many associations with inverse="true". For these associations, the update is handled by the many-to-one end of the association, and so considerations of collection update performance simply do not apply.
しかし、よくデザインされたHibernateのドメインモデルでは、通常もっとも多いコレクションは事実上 inverse="true" を指定した1対多関連です。これらの関連では、更新は多対一の関連端で扱われ、コレクションの更新パフォーマンスの問題は当てはまりません。
19.5.3. Bags and lists are the most efficient inverse collections(inverseコレクションにもっとも最適なbaglist)
Just before you ditch bags forever, there is a particular case in which bags (and also lists) are much more performant than sets. For a collection with inverse="true" (the standard bidirectional one-to-many relationship idiom, for example) we can add elements to a bag or list without needing to initialize (fetch) the bag elements! This is because Collection.add() or Collection.addAll() must always return true for a bag or List(unlike a Set). This can make the following common code much faster.
bagを見放してしまう前に、bag(そしてlistも)がsetよりもずっとパフォーマンスが良い特別なケースを紹介します。 inverse="true" のコレクション(一般的な1対多関連の使い方など)で、bagの要素を初期化(フェッチ)する必要なくbaglistに要素を追加できます!これは Collection.add()  Collection.addAll() bag List では常にtrueを返さなければならないからです( Set とは異なります)。これは以下の共通処理をより速くすることができます。
Parent p = (Parent) sess.load(Parent.class, id);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);  //no need to fetch the collection!
sess.flush();
19.5.4. One shot delete(一括削除)
Occasionally, deleting collection elements one by one can be extremely inefficient. Hibernate isn't completely stupid, so it knows not to do that in the case of an newly-empty collection (if you called list.clear(), for example). In this case, Hibernate will issue a single DELETE and we are done!
時々、コレクションの要素を一つ一つ削除することは極めて非効率的になることがあります。Hibernateは愚かではないので、新しい空のコレクションの場合( list.clear() を呼び出した場合など)ではこれをすべきでないことを知っています。この場合は、HibernateDELETE を一回発行して、それですべて終わります!
Suppose we add a single element to a collection of size twenty and then remove two elements. Hibernate will issue one INSERT statement and two DELETE statements (unless the collection is a bag). This is certainly desirable.
サイズ20のコレクションに一つの要素を追加し、それから二つの要素を削除するとします。Hibernateは一つの INSERT 文と二つの DELETE 文を発行します(コレクションがbagでなければ)。これは確かに望ましい動作です。
However, suppose that we remove eighteen elements, leaving two and then add thee new elements. There are two possible ways to proceed
しかし、18個の要素を削除して2つを残し、それから3つ新しい要素を追加するとします。このとき二つの方法があります。
?         delete eighteen rows one by one and then insert three rows(18行を一つ一つ削除して、3行を追加する)
?         remove the whole collection (in one SQL DELETE) and insert all five current elements (one by one)( コレクション全体を削除( DELETE SQLを一回)し、そして5つの要素すべてを(一つずつ)追加する)
Hibernate isn't smart enough to know that the second option is probably quicker in this case. (And it would probably be undesirable for Hibernate to be that smart; such behaviour might confuse database triggers, etc.)
Hibernateはこの場合に2番目の方法がより速いだろうとわかるほど賢くはありません。(そしてHibernateがこのように賢いことも望ましくないでしょう。このような振る舞いはデータベースのトリガなどを混乱させるかもしれません。)
Fortunately, you can force this behaviour (ie. the second strategy) at any time by discarding (ie. dereferencing) the original collection and returning a newly instantiated collection with all the current elements. This can be very useful and powerful from time to time.
幸いにも、元のコレクションを捨て(つまり参照をやめて)、現在の要素をすべて持つ新しいコレクションのインスタンスを返すことで、いつでもこの振る舞い(2番目の戦略)を強制することが出来ます。時にこれはとても便利で強力です。
Of course, one-shot-delete does not apply to collections mapped inverse="true".
もちろん、一括削除は inverse="true" を指定したコレクションには行いません。
19.6. Monitoring performance(パフォーマンスのモニターリング)
Optimization is not much use without monitoring and access to performance numbers. Hibernate provides a full range of figures about its internal operations. Statistics in Hibernate are available per SessionFactory.
最適化はモニタリングやパフォーマンスを示す数値がなければ十分に行えません。Hibernateは内部処理のすべての範囲の数値を提供します。Hibernateの統計情報はSessionFactory 単位で取得可能です。
19.6.1. Monitoring a SessionFactory(SessionFactoryのモニターリング)
You can access SessionFactory metrics in two ways. Your first option is to callsessionFactory.getStatistics() and read or display the Statistics yourself.
SessionFactory のメトリクスにアクセスするには2つの方法があります。最初の方法は、sessionFactory.getStatistics() を呼び出し、自分で Statistics の読み込みや表示を行います。
Hibernate can also use JMX to publish metrics if you enable the StatisticsService MBean. You may enable a single MBean for all your SessionFactory or one per factory. See the following code for minimalistic configuration examples:
StatisticsService MBeanを有効にしていれば、HibernateJMXを使ってメトリクスを発行することもできます。1つのMBeanをすべての SessionFactory に対して有効にするか、SessionFactoryごとに一つのMBeanを有効にすることが出来ます。最小限の設定例である以下のコードを見てください。
// MBean service registration for a specific SessionFactory
Hashtable tb = new Hashtable();
tb.put("type", "statistics");
tb.put("sessionFactory", "myFinancialApp");
ObjectName on = new ObjectName("hibernate", tb); // MBean object name

StatisticsService stats = new StatisticsService(); // MBean implementation
stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
server.registerMBean(stats, on); // Register the Mbean on the server
// MBean service registration for all SessionFactory's
Hashtable tb = new Hashtable();
tb.put("type", "statistics");
tb.put("sessionFactory", "all");
ObjectName on = new ObjectName("hibernate", tb); // MBean object name

StatisticsService stats = new StatisticsService(); // MBean implementation
server.registerMBean(stats, on); // Register the MBean on the server
TODO: This doesn't make sense: In the first case, we retrieve and use the MBean directly. In the second one, we must give the JNDI name in which the session factory is held before using it. UsehibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")
TODO: これは意味がありません。最初のケースは、MBeanを直接復元して使用します。2番目のケースは、使う前にsession factoryが持っているJNDI名を渡さなければなりません。hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name") を使ってください。
You can (de)activate the monitoring for a SessionFactory
SessionFactory に対してモニタリングの開始(終了)を行うことが出来ます。
?         at configuration time, set hibernate.generate_statistics to false
設定時には、 hibernate.generate_statistics  false にします
?         at runtime: sf.getStatistics().setStatisticsEnabled(true) orhibernateStatsBean.setStatisticsEnabled(true)
実行時に、 sf.getStatistics().setStatisticsEnabled(true) またはhibernateStatsBean.setStatisticsEnabled(true) を呼び出します
Statistics can be reset programatically using the clear() method. A summary can be sent to a logger (info level) using the logSummary() method.
統計は clear() メソッドを使って手動でリセットすることが出来ます。サマリはlogSummary() メソッドを使ってloggerに送ることが出来ます(infoレベルです)。
19.6.2. Metrics(マトリックス)
Hibernate provides a number of metrics, from very basic to the specialized information only relevant in certain scenarios. All available counters are described in the Statisticsinterface API, in three categories:
Hibernateは、特定のシナリオで関連した専門情報に基本的な数多くのマトリックスを提供します。すべての使用可能なカウンタは Statistics インターフェイスのAPIに書かれており、3つの分類があります。
?         Metrics related to the general Session usage, such as number of open sessions, retrieved JDBC connections, etc.
メトリクスは一般的な Session の使い方と関係しています。オープンしたセッションの数がJDBCコネクションと関連しているのと同じです。
?         Metrics related to he entities, collections, queries, and caches as a whole (aka global metrics),
メトリクスは要素、コレクション、クエリやキャッシュなど全体に関係しています(別名はグローバルメトリクスです)。
?         Detailed metrics related to a particular entity, collection, query or cache region.
メトリクスの詳細は特定のエンティティ、コレクション、クエリ、キャッシュ領域に関係しています。
For exampl,e you can check the cache hit, miss, and put ratio of entities, collections and queries, and the average time a query needs. Beware that the number of milliseconds is subject to approximation in Java. Hibernate is tied to the JVM precision, on some platforms this might even only be accurate to 10 seconds.
例として、キャッシュのヒット、ヒットミスや、要素、コレクション、クエリの割合、クエリの実行に必要な平均時間を確認できます。ミリ秒の数値はJavaの近似を受けることに注意してください。HibernateJVMの精度に制限され、プラットフォームによっては10秒単位でしか正確でないかもしれません。
Simple getters are used to access the global metrics (i.e. not tied to a particular entity, collection, cache region, etc.). You can access the metrics of a particular entity, collection or cache region through its name, and through its HQL or SQL representation for queries. Please refer to the StatisticsEntityStatisticsCollectionStatistics,SecondLevelCacheStatistics, and QueryStatistics API Javadoc for more information. The following code shows a simple example:
単純なgetterはグローバルメトリクス(すなわち特定のエンティティ、コレクション、キャッシュ領域などに縛られない)にアクセスするために使います。特定のエンティティ、コレクション、キャッシュ領域のメトリクスは、それらの名前や、クエリのHQLSQL表現によってアクセスすることが出来ます。さらに詳しい情報は、Statistics EntityStatistics  CollectionStatistics  SecondLevelCacheStatistics  QueryStatistics APIjavadocを参照してください。以下のコードは簡単な例です。
Statistics stats = HibernateUtil.sessionFactory.getStatistics();

double queryCacheHitCount  = stats.getQueryCacheHitCount();
double queryCacheMissCount = stats.getQueryCacheMissCount();
double queryCacheHitRatio =
  queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);

log.info("Query Hit ratio:" + queryCacheHitRatio);

EntityStatistics entityStats =
  stats.getEntityStatistics( Cat.class.getName() );
long changes =
        entityStats.getInsertCount()
        + entityStats.getUpdateCount()
        + entityStats.getDeleteCount();
log.info(Cat.class.getName() + " changed " + changes + "times"  );
To work on all entities, collections, queries and region caches, you can retrieve the list of names of entities, collections, queries and region caches with the following methods:getQueries()getEntityNames()getCollectionRoleNames(), andgetSecondLevelCacheRegionNames().
すべてのエンティティ、コレクション、クエリ、キャッシュ領域に対して行う場合は、getQueries()  getEntityNames() getCollectionRoleNames() getSecondLevelCacheRegionNames() メソッドでそれぞれの名前のリストを取得することが出来ます。

No comments:

Post a Comment