blob: 3a69cd7a695623fb96800c278b70f4a8f5f8619d [file] [log] [blame]
Title: Nested DataContexts
<P>One of the goals of the DataContext is to provide an isolated area where local object changes can be performed without affecting other similar areas or the underlying storage. At some point in time users would either commit changes to the underlying storage or undo them (roll them back). </P>
<P>If a DataContext is directly attached to the DataDomain, a call to <TT>DataContext.commitChanges()</TT> results in changes written to the database. On the other hand if DataContext's direct parent in the access stack is not a DataDomain, but another DataContext, changes can be saved to the parent without saving them to the database. Such child context is often called &quot;nested&quot;.</P>
<P>Nested contexts are useful in many situations, such as nested UI dialogs, complicated workflows, etc.</P>
<H3><A name="NestedDataContexts-CreatingNestedDataContext"></A>Creating Nested DataContext</H3>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">DataContext parent = ...
DataContext child = context.createChildDataContext();</PRE>
</DIV></DIV>
<P>Note that if there was a DataContextFactory configured for the DataDomain at the top of the context hierarchy, such factory will be used internally by <TT>createChildDataContext</TT> method. Also child DataContext inherits parent's <TT>&quot;ValidatingObjectsOnCommit&quot;</TT> property.</P>
<H3><A name="NestedDataContexts-UsingNestedDataContext"></A>Using Nested DataContext</H3>
<P>A nested DataContext does everything a regular DataContext can do, i.e. perform queries, register new objects, delete objects, etc. A specific behavior is the ability to choose between a cascading or one-level commit or rollback.</P>
<P>Regular <TT>&quot;commitChanges&quot;</TT> call does a cascading commit through the stack of parents all the way to the database:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">child.commitChanges();</PRE>
</DIV></DIV>
<P>However it is possible to commit to parent, without triggering a DB commit:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">child.commitChangesToParent();</PRE>
</DIV></DIV>
<P>Same thing with rollback, <TT>&quot;rollbackChanges&quot;</TT> does a cascading rollback:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">child.rollbackChanges();</PRE>
</DIV></DIV>
<P>While <TT>&quot;rollbackChangesLocally&quot;</TT> only affects the nested context, and not even sent to the parent:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">child.rollbackChangesLocally();</PRE>
</DIV></DIV>
<H3><A name="NestedDataContexts-NestedDataContextsPerformance"></A>Nested DataContexts Performance</H3>
<P>All cascading operations (such as a select query or a cascading update) initiated by a nested DataContext will have to travel through the stack of parent contexts, incurring certain delay at each stack level. The delay is due to the fact that each DataContext has to update its own objects during most operations. So nesting should only be used when application specifics require to do so. Also nesting of more than a few levels should be avoided.</P>