diff --git a/reference/en/modules/collection_mapping.xml b/reference/en/modules/collection_mapping.xml
index 9bbd780e76..e01cf34792 100644
--- a/reference/en/modules/collection_mapping.xml
+++ b/reference/en/modules/collection_mapping.xml
@@ -566,109 +566,6 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set
-
- Lazy Initialization
-
-
- Collections (other than arrays) may be lazily initialized, meaning they load
- their state from the database only when the application needs to access it.
- Initialization of collections owned by persistent instances happens transparently
- to the user, so the application would not normally need to worry about this (in
- fact, transparent lazy initialization is the main reason why Hibernate needs its
- own collection implementations). However, if the application tries something like
- this:
-
-
-
-
-
- It could be in for a nasty surprise. 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
- line that reads from the collection to just before the commit. (There are
- other more advanced ways to solve this problem, however.)
-
-
-
- It's possible to use a non-lazy collection. However, it is intended that lazy
- initialization be used for almost all collections, especially for collections
- of entities, and is now the default. 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!
-
-
-
- Exceptions that occur while lazily initializing a collection are wrapped in a
- LazyInitializationException.
-
-
-
- In some application architectures, particularly where the code that accesses data
- using Hibernate, and the code that uses it are in different application layers, it
- can be a problem to ensure that the Session is open when a
- collection is initialized. They are two basic ways to deal with this issue:
-
-
-
-
-
- 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. Of course, this places heavy
- demands upon the correctness of the exception handling of your application
- infrastructure. It is vitally important that the Session
- is closed and the transaction ended before returning to the user, even
- when an exception occurs during rendering of the view. The servlet filter
- has to be able to access the Session for this approach.
- We recommend that a ThreadLocal variable be used to
- hold the current Session (see chapter 1,
- , for an example implementation).
-
-
-
-
- In an application with a seperate 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.
-
-
-
-
- You may also attach a previously loaded object to a new Session
- with update() or lock() before
- accessing unitialized collections (or other proxies). Hibernate can not
- do this automatically, as it would introduce ad hoc transaction semantics!
-
-
-
-
-
- You can use a collection filter to get the size of a collection without initializing it:
-
-
-
-
-
- The createFilter() method is also used to efficiently retrieve subsets
- of a collection without needing to initialize the whole collection. (And the new
- <filter> functionality is a more powerful approach.)
-
-
-
-
Sorted Collections
diff --git a/reference/en/modules/configuration.xml b/reference/en/modules/configuration.xml
index afce6ec061..7b59ec13be 100644
--- a/reference/en/modules/configuration.xml
+++ b/reference/en/modules/configuration.xml
@@ -876,7 +876,7 @@ hibernate.dialect = \
-
+
Outer Join Fetching
@@ -888,30 +888,20 @@ hibernate.dialect = \
in a single SQL SELECT.
-
- By default, the fetched graph when loading an objects ends at leaf objects,
- collections, objects with proxies, or where circularities occur in the case
- of *-to-one associations. Hibernate will however execute an immediate additional
- SELECT for any persistent collection (we recommend that you
- turn on lazy loading for all collection mappings).
-
-
-
- For a particular association, fetching may be enabled
- or disabled (and the default behaviour overridden) by setting the
- outer-join attribute in the XML mapping.
-
-
Outer join fetching may be disabled globally by setting
the property hibernate.max_fetch_depth to 0.
A setting of 1 or higher enables outer join fetching for
- all one-to-one and many-to-one associations, which are, also by default, set
- to auto outer join. However, one-to-many associations and
- collections are never fetched with an outer-join, unless explicitly declared
- for each particular association. This behavior can also be overriden at runtime
- with Hibernate queries. See the query chapters in the documentation for more
- details.
+ all one-to-one and many-to-one associations if no other fetching strategy is
+ defined in the mapping and if proxying of the target entity
+ class has been turned off (thus disabling lazy loading). However, one-to-many
+ associations and collections are never fetched with an outer-join, unless
+ explicitly declared for each particular association. This
+ behavior can also be overriden at runtime with Hibernate queries.
+
+
+
+ See for more information.
diff --git a/reference/en/modules/manipulating_data.xml b/reference/en/modules/manipulating_data.xml
index 2643c36aeb..5b5806a99e 100644
--- a/reference/en/modules/manipulating_data.xml
+++ b/reference/en/modules/manipulating_data.xml
@@ -2,7 +2,7 @@
Working with Persistent Data
-
+
Creating a persistent object
@@ -24,6 +24,8 @@ Long generatedId = (Long) sess.save(fritz);]]>
is called. If Cat has an assigned
identifier, or a composite key, the identifier should be assigned to
the cat instance before calling save().
+ You may also use create() instead of save(),
+ with the semantics defined in the EJB3 early draft.
@@ -105,14 +107,16 @@ return cat;]]>
You may even load an object using an SQL SELECT ... FOR UPDATE.
- See the next section for a discussion of Hibernate LockModes.
+ See the next sections for a discussion of Hibernate LockModes.
Note that any associated instances or contained collections are
- not selected FOR UPDATE.
+ not selected FOR UPDATE, unless you decide
+ to specify lock or all as a
+ cascade style for the association.
@@ -125,6 +129,13 @@ return cat;]]>
sess.flush(); //force the SQL INSERT
sess.refresh(cat); //re-read the state (after the trigger executes)]]>
+
+ An important question usually appears at this point: How much does Hibernate load
+ from the database and how many SQL SELECTs will it use? This
+ depends on the fetching strategy and is explained in
+ .
+
+
diff --git a/reference/en/modules/performance.xml b/reference/en/modules/performance.xml
index b75ca92fc2..8674311243 100644
--- a/reference/en/modules/performance.xml
+++ b/reference/en/modules/performance.xml
@@ -196,238 +196,487 @@
-
- We have already shown how you can use lazy initialization for persistent collections
- in the chapter about collection mappings. A similar effect is achievable for ordinary object
- references, using CGLIB proxies. We have also mentioned how Hibernate caches persistent
- objects at the level of a Session. More aggressive caching strategies
- may be configured upon a class-by-class basis.
-
-
-
- In the next section, we show you how to use these features, which may be used to
- achieve much higher performance, where necessary.
-
-
-
- Proxies for Lazy Initialization
+
+ Fetching strategies
- Hibernate implements lazy initializing proxies for persistent objects using runtime
- bytecode enhancement (via the excellent CGLIB library).
+ A fetching strategy describes the number of instances, the depth of a
+ subgraph of instances, and SQL SELECTs that are used
+ to retrieve these instances. Hibernate supports several strategies and you
+ can configure them on a global level, per entity class, per association, or
+ even for a particular query in HQL and with Criteria.
- The mapping file may declare an interface to use as the proxy interface for that
- class. By default, Hibernate uses a subclass of the class itself. (The proxied
- class must implement a default constructor with at least package visibility.)
-
-
-
- There are some gotchas to be aware of when extending this approach to polymorphic
- classes, eg.
+ Hibernate offers the following fetching strategies:
-
- ......
-
- .....
-
-]]>
-
-
- Firstly, instances of Cat will never be castable to
- DomesticCat, even if the underlying instance is an
- instance of DomesticCat.
-
-
-
-
-
- Secondly, it is possible to break proxy ==.
-
-
-
-
-
- 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:
-
-
-
-
-
- Third, you may not use a CGLIB proxy for a final class or a class
- with any final methods.
-
-
-
- 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 inheritence 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.
-
-
-
- ......
-
- .....
-
-]]>
-
-
- where Cat implements the interface ICat and
- DomesticCat implements the interface IDomesticCat. Then
- proxies for instances of Cat and DomesticCat may be returned
- by load() or iterate(). (Note that find()
- does not usually return proxies.)
-
-
-
-
-
- Relationships are also lazily initialized. This means you must declare any properties to be of
- type Cat, not CatImpl.
-
-
-
- Certain operations do not require proxy initialization
-
-
-
+
- equals(), if the persistent class does not override
- equals()
+ Lazy fetching - an associated instance (or a
+ collection) will only be loaded when needed, using an additional
+ defered SELECT.
- hashCode(), if the persistent class does not override
- hashCode()
+ Batch fetching - an optimization strategy
+ for lazy fetching, Hibernate not only retrieves a single instance
+ (or collection), but several in the same SELECT.
- The identifier getter method
+ Eager fetching - Hibernate retrieves the
+ associated instance (or collection) in the same SELECT,
+ using an OUTER JOIN.
+
+
+
+
+ Select fetching - a second SELECT
+ is used to retrieve the associated instance (or collection), but
+ it might be executed immediately and not defered until first access
+ (as with lazy fetching).
-
+
- Hibernate will detect persistent classes that override equals() or
- hashCode().
+ By default, Hibernate3 will only load the given entity using a single
+ SELECT statement if you retrieve an object with
+ load() or get(). This means that
+ all single-ended associations and collections are set for lazy fetching
+ by default. You can change this global default by setting the
+ default-lazy attribute on the hibernate-mapping
+ element to false.
- Exceptions that occur while initializing a proxy are wrapped in a
- LazyInitializationException.
-
-
-
- Sometimes we need to ensure that a proxy or collection is initialized before closing the
- Session. Of course, we can alway force initialization by calling
- cat.getSex() or cat.getKittens().size(), for example.
- But that is confusing to readers of the code and is not convenient for generic code.
- The static methods Hibernate.initialize() and Hibernate.isInitialized()
- provide the application with a convenient way of working with lazyily 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.
-
-
-
-
-
- Using batch fetching
-
-
- Hibernate can make efficient use of batch fetching, that is, Hibernate can load several uninitialized
- proxies if one proxy is accessed. Batch fetching is an optimization for the lazy loading strategy.
- There are two ways you can tune batch fetching: on the class and the collection level.
+ We'll now have a closer look at the individual fetching strategies and how
+ to change them for single-ended associations and collections.
-
- 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
- Cat has 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:
-
+
+ Collection fetching
- ...]]>
+
+ Initialization of collections owned by persistent instances happens transparently
+ to the user, so the application would not normally need to worry about this (in
+ fact, transparent lazy initialization is the main reason why Hibernate needs its
+ own collection implementations). However, if the application tries something like
+ this:
+
-
- Hibernate will now execute only three queries, the pattern is 10, 10, 5. You can see that batch fetching
- is a blind guess, as far as performance optimization goes, it depends on the number of unitilized proxies
- in a particular Session.
-
+
- 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:
-
+Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]>
-
+
+ It could be in for a nasty surprise. 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
+ line that reads from the collection to just before the commit. (There are
+ other more advanced ways to solve this problem, some are discussed later.)
+
+
+
+ It's possible to use a non-lazy collection. However, it is intended that lazy
+ initialization be used for almost all collections, especially for collections
+ of entity references (its the default). 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! Still, sometimes you want to use an additional
+ SELECT for a particular collection right away, not defered
+ until the first access happens:
+
+
+
+
+
+
+
+
+ Hibernate will now execute an immediate second SELECT loading
+ the collection of Permission instances, when a particular
+ User is retrieved.
+
+
+
+ Any kind of lazy fetching (and also Select fetching) is extremely vulnerable to
+ N+1 selects problems. So usually, we choose lazy fetching only as a default
+ strategy, and override it for a particular transaction, using the HQL
+ LEFT JOIN FETCH clause. This tells Hibernate to fetch the
+ association eagerly in the first select, using an outer join. In the
+ Criteria API, you would use
+ setFetchMode(FetchMode.EAGER).
+
+
+
+ You can always force outer join association fetching in the mapping file, by setting
+ fetch="join" (or use the old outer-join="true"
+ syntax). We don't recommend this setting, especially not for collections, since it is
+ incredibly rare to find an entity which is always used when
+ an associated entity is used, at least in a sufficiently large system.
+
+
+
+ Eager fetching for collections has another restriction: you may only set one
+ collection role per persistent class to be fetched per outer join. Hibernate forbids
+ Cartesian products when possible, SELECTing two collections per
+ outer join would create one. This would almost always be slower than two (lazy or
+ non-defered) SELECTs. The restriction to a single outer-joined
+ collection applies to both the mapping fetching strategies and to HQL/Criteria queries.
+
+
+
+
+
+ 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).
+
+
+
+ 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.
+
+
+
+ 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!
+
+
+
+ There are some gotchas to be aware of when extending this approach to polymorphic
+ classes, eg.
+
+
+
+ ......
+
+ .....
+
+ ]]>
+
+
+ Firstly, instances of Cat will never be castable to
+ DomesticCat, even if the underlying instance is an
+ instance of DomesticCat:
+
+
+
+
+
+ Secondly, it is possible to break proxy ==.
+
+
+
+
+
+ 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:
+
+
+
+
+
+ Third, you may not use a CGLIB proxy for a final class or a class
+ with any final methods.
+
+
+
+ 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 inheritence 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.
+
+
+
+ ......
+
+ .....
+
+ ]]>
+
+
+ where Cat implements the interface ICat and
+ DomesticCat implements the interface IDomesticCat. Then
+ proxies for instances of Cat and DomesticCat may be returned
+ by load() or iterate(). (Note that find()
+ does not usually return proxies.)
+
+
+
+
+
+ Relationships are also lazily initialized. This means you must declare any properties to be of
+ type Cat, not CatImpl.
+
+
+
+ Certain operations do not require proxy initialization
+
+
+
+
+
+ equals(), if the persistent class does not override
+ equals()
+
+
+
+
+ hashCode(), if the persistent class does not override
+ hashCode()
+
+
+
+
+ The identifier getter method
+
+
+
+
+
+ Hibernate will detect persistent classes that override equals() or
+ hashCode().
+
+
+
+ You may of course also use Eager or Select fetching strategies for single-ended
+ associations:
+
+
+
+]]>
+
+
+ The first mapping tells Hibernate to fetch the associated mother
+ entity in the same initial SELECT using an OUTER JOIN.
+ You can set this option on as many *-to-one associations as you like, there is no
+ danger of creating a Cartesian product (opposed to collections). Note that you can
+ set the maximum depth of outer joined tables with the global configuration option
+ max_fetch_depth (see ).
+
+
+
+ The second mapping enables an additional SELECT for the
+ retrieval of the father. Note that Hibernate does not guarantee
+ when this query will be executed. If it should be executed
+ immediately (right after the initial SELECT), disable proxying
+ on the target of the association by setting it to lazy="false":
+
+
+ ...]]>
+
+
+ (Note that this example uses only a single persistent class Cat
+ and self-referencing associations. This doesn't change the fetching behavior, as expexted.)
+
+
+
+
+
+ Initializing collections and proxies
+
+
+ An exception (LazyInitializationException) will be thrown by
+ Hibernate if an unitialized 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 detached state.
+
+
+
+ Sometimes we need to ensure that a proxy or collection is initialized before closing the
+ Session. Of course, we can alway force initialization by calling
+ cat.getSex() or cat.getKittens().size(), for example.
+ But that is confusing to readers of the code and is not convenient for generic code.
+
+
+
+ The static methods Hibernate.initialize() and Hibernate.isInitialized()
+ provide the application with a convenient way of working with lazyily 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.
+
+
+
+ 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, 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:
+
+
+
+
+
+ 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 the Session
+ is closed and the transaction ended before returning to the user, even
+ when an exception occurs during rendering of the view. The servlet filter
+ has to be able to access the Session for this approach.
+ We recommend that a ThreadLocal variable be used to
+ hold the current Session (see chapter 1,
+ , for an example implementation).
+
+
+
+
+ In an application with a seperate 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.
+
+
+
+
+ You may also attach a previously loaded object to a new Session
+ with merge() or lock() before
+ accessing unitialized collections (or other proxies). Hibernate can not
+ do this automatically, as it would introduce ad hoc transaction semantics!
+
+
+
+
+
+ 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:
+
+
+
+
+
+ The createFilter() method is also used to efficiently retrieve subsets
+ of a collection without needing to initialize the whole collection:
+
+
+
+
+
+
+
+ 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 for the lazy
+ loading strategy. There are two ways you can tune batch fetching: on the class and the collection level.
+
+
+
+ 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
+ Cat has 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:
+
+
+ ...]]>
+
+
+ Hibernate will now execute only three queries, the pattern is 10, 10, 5. You can see that batch fetching
+ is a blind guess, as far as performance optimization goes, it depends on the number of unitilized proxies
+ in a particular Session.
+
+
+
+ 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:
+
+
+
...
]]>
-
- With a batch-size of 3, Hibernate will load 3, 3, 3, 1 collections in 4
- SELECTs. Again, the value of the attribute depends on the expected number of
- uninitialized collections in a particular Session.
-
+
+ With a batch-size of 3, Hibernate will load 3, 3, 3, 1 collections in 4
+ SELECTs. Again, the value of the attribute depends on the expected number of
+ uninitialized collections in a particular Session.
+
-
- Batch fetching of collections is particularly useful if you have a nested tree of items, ie.
- the typical bill-of-materials pattern.
-
+
+ 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 path might be a better option for read-mostly trees.)
+
-
-
-
- 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.
-
-
-
- To enable lazy property loading, set the lazy attribute on your
- particular property mappings:
-
+
+ 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.
+
+
+
+ To enable lazy property loading, set the lazy attribute on your
+ particular property mappings:
+
+
+
@@ -436,17 +685,17 @@ Cat fritz = (Cat) iter.next();]]>
]]>
-
- 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.
-
+
+ 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.
+
-
- For bytecode instrumentation, use the following Ant task:
-
+
+ For bytecode instrumentation, use the following Ant task:
+
-
+
@@ -460,42 +709,23 @@ Cat fritz = (Cat) iter.next();]]>
]]>
-
- A different (better?) way to avoid unnecessary column reads, at least for
- read-only transactons is to use the projection features of HQL. This avoids
- the need for buildtime bytecode processing.
-
+
+ A different (better?) way to avoid unnecessary column reads, at least for
+ read-only transactons is to use the projection features of HQL. This avoids
+ the need for buildtime bytecode processing.
+
+
+
+ TODO: Document issues with lazy property loading
+
+
+
- TODO: Document issues with lazy property loading
-
-
-
-
-
- Outer join fetching
-
-
- Any kind of lazy fetching is extremely vulnerable to N+1 selects problems. So usually,
- we choose lazy fetching only as a "default" strategy, and override it for a particular
- transaction, using the HQL LEFT JOIN FETCH clause. This tells Hibernate
- to fetch the association in the first select, using an outer join. In the
- Criteria API, you would use setFetchMode(FetchMode.EAGER).
-
-
-
- You can always force outer join association fetching in the mapping file, by setting
- outer-join="true". We don't recommend this setting, especially
- not for collections, since it is incredibly rare to find an entity which is
- always used when an associated entity is used, at least in a
- sufficiently large system.
-
-
-
- A completely different way to avoid problems with N+1 selects is to use the second-level
+ A completely different way to avoid problems with N+1 selects is to use the second-level
cache.
-
+
diff --git a/reference/en/modules/query_criteria.xml b/reference/en/modules/query_criteria.xml
index 0fbd5adfcf..73fd911f0a 100644
--- a/reference/en/modules/query_criteria.xml
+++ b/reference/en/modules/query_criteria.xml
@@ -148,7 +148,7 @@ while ( iter.hasNext() ) {
-
+
Dynamic association fetching
@@ -164,7 +164,7 @@ while ( iter.hasNext() ) {
This query will fetch both mate and kittens
- by outer join.
+ by outer join. See for more information.
diff --git a/reference/en/modules/query_hql.xml b/reference/en/modules/query_hql.xml
index 491246be89..9b6c6f2d7d 100644
--- a/reference/en/modules/query_hql.xml
+++ b/reference/en/modules/query_hql.xml
@@ -72,7 +72,7 @@
-
+
Associations and joins
@@ -123,12 +123,13 @@ from Formula form full join form.parameter param]]>
-
+
In addition, a "fetch" join allows associations or collections of values to be
initialized along with their parent objects, using a single select. This is particularly
useful in the case of a collection. It effectively overrides the outer join and
- lazy declarations of the mapping file for associations and collections.
+ lazy declarations of the mapping file for associations and collections. See
+ for more information.