minor changes to collections

git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@4413 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gavin King 2004-08-22 10:44:54 +00:00
parent 2a1bf738da
commit 0ec2e527fc
1 changed files with 26 additions and 18 deletions

View File

@ -572,10 +572,11 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set
<para>
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 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:
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:
</para>
<programlisting><![CDATA[s = sessions.openSession();
@ -588,17 +589,20 @@ Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></prog
<para>
It could be in for a nasty surprise. Since the permissions collection was not
initialized when the <literal>Session</literal> was committed,
the collection will never be able to load its state. The fix is to move the
initialized when the <literal>Session</literal> was closed, the collection
will not be able to load its state. <emphasis>Hibernate does not support lazy
initialization for detached objects</emphasis>. 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.)
</para>
<para>
Alternatively, use a non-lazy collection. Since lazy initialization can lead to
It's possible to use a non-lazy collection. Since lazy initialization can lead to
bugs like that above, non-laziness is the default. However, it is intended that
lazy initialization be used for almost all collections, especially for
collections of entities (for reasons of efficiency).
lazy initialization be used for almost all collections, especially for collections
of entities (for reasons of efficiency). 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!
</para>
<para>
@ -662,16 +666,15 @@ Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></prog
</itemizedlist>
<para>
You can use the <literal>filter()</literal> method of the Hibernate Session API to
get the size of a collection without initializing it:
You can use a collection filter to get the size of a collection without initializing it:
</para>
<programlisting><![CDATA[( (Integer) s.filter( collection, "select count(*)" ).get(0) ).intValue()]]></programlisting>
<programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
<para>
<literal>filter()</literal> or <literal>createFilter()</literal> are also used to
efficiently retrieve subsets of a collection without needing to initialize the whole
collection.
The <literal>createFilter()</literal> method is also used to efficiently retrieve subsets
of a collection without needing to initialize the whole collection. (And the new
<literal>&lt;filter&gt;</literal> functionality is a more powerful approach.)
</para>
</sect1>
@ -905,9 +908,9 @@ session.update(category); // The relationship will be saved]]></
<title>Ternary Associations</title>
<para>
There are two possible approaches to mapping a ternary association. One approach is to use
composite elements (discussed below). Another is to use a <literal>Map</literal> with an
association as its index:
There are three possible approaches to mapping a ternary association. One approach
is to use composite elements (discussed below). Another is to use a <literal>Map</literal>
with an association as its index:
</para>
<programlisting><![CDATA[<map name="contracts" lazy="true">
@ -922,6 +925,11 @@ session.update(category); // The relationship will be saved]]></
<many-to-many column="connection_id" class="Connection"/>
</map>]]></programlisting>
<para>
A final alternative is to simply remodel the association as an entity class. This
is the approach we use most commonly.
</para>
</sect1>
<sect1 id="collections-heterogeneous">