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> <para>
Collections (other than arrays) may be lazily initialized, meaning they load Collections (other than arrays) may be lazily initialized, meaning they load
their state from the database only when the application needs to access it. their state from the database only when the application needs to access it.
Initialization happens transparently to the user so the application would not Initialization of collections owned by persistent instances happens transparently
normally need to worry about this (in fact, transparent lazy initialization is to the user, so the application would not normally need to worry about this (in
the main reason why Hibernate needs its own collection implementations). fact, transparent lazy initialization is the main reason why Hibernate needs its
However, if the application tries something like this: own collection implementations). However, if the application tries something like
this:
</para> </para>
<programlisting><![CDATA[s = sessions.openSession(); <programlisting><![CDATA[s = sessions.openSession();
@ -588,17 +589,20 @@ Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></prog
<para> <para>
It could be in for a nasty surprise. Since the permissions collection was not It could be in for a nasty surprise. Since the permissions collection was not
initialized when the <literal>Session</literal> was committed, initialized when the <literal>Session</literal> was closed, the collection
the collection will never be able to load its state. The fix is to move the 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 line that reads from the collection to just before the commit. (There are
other more advanced ways to solve this problem, however.) other more advanced ways to solve this problem, however.)
</para> </para>
<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 bugs like that above, non-laziness is the default. However, it is intended that
lazy initialization be used for almost all collections, especially for lazy initialization be used for almost all collections, especially for collections
collections of entities (for reasons of efficiency). 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>
<para> <para>
@ -662,16 +666,15 @@ Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></prog
</itemizedlist> </itemizedlist>
<para> <para>
You can use the <literal>filter()</literal> method of the Hibernate Session API to You can use a collection filter to get the size of a collection without initializing it:
get the size of a collection without initializing it:
</para> </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> <para>
<literal>filter()</literal> or <literal>createFilter()</literal> are also used to The <literal>createFilter()</literal> method is also used to efficiently retrieve subsets
efficiently retrieve subsets of a collection without needing to initialize the whole of a collection without needing to initialize the whole collection. (And the new
collection. <literal>&lt;filter&gt;</literal> functionality is a more powerful approach.)
</para> </para>
</sect1> </sect1>
@ -905,9 +908,9 @@ session.update(category); // The relationship will be saved]]></
<title>Ternary Associations</title> <title>Ternary Associations</title>
<para> <para>
There are two possible approaches to mapping a ternary association. One approach is to use There are three possible approaches to mapping a ternary association. One approach
composite elements (discussed below). Another is to use a <literal>Map</literal> with an is to use composite elements (discussed below). Another is to use a <literal>Map</literal>
association as its index: with an association as its index:
</para> </para>
<programlisting><![CDATA[<map name="contracts" lazy="true"> <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"/> <many-to-many column="connection_id" class="Connection"/>
</map>]]></programlisting> </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>
<sect1 id="collections-heterogeneous"> <sect1 id="collections-heterogeneous">