From: Michael D. <mik...@us...> - 2005-05-04 14:49:09
|
Update of /cvsroot/nhibernate/nhibernate/doc/reference/en/modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15453 Modified Files: basic_mapping.xml example_parentchild.xml Log Message: updated for next build Index: basic_mapping.xml =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/doc/reference/en/modules/basic_mapping.xml,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** basic_mapping.xml 4 May 2005 03:13:17 -0000 1.13 --- basic_mapping.xml 4 May 2005 14:48:57 -0000 1.14 *************** *** 720,723 **** --- 720,724 ---- type="discriminator_type"<co id="discriminator2-co" linkends="discriminator2" /> force="true|false"<co id="discriminator3-co" linkends="discriminator3" /> + insert="true|false" <co id="discriminator4-co" linkends="discriminator4" /> /></programlisting> <calloutlist> *************** *** 740,743 **** --- 741,751 ---- all instances of the root class. </para> + </callout> + <callout arearefs="discriminator4-co" id="discriminator4"> + <para> + <literal>insert</literal> (optional - defaults to <literal>true</literal>) + set this to <literal>false</literal> if your discriminator column is also part + of a mapped composite identifier. + </para> </callout> </calloutlist> *************** *** 770,773 **** --- 778,782 ---- type="typename"<co id="version3-co" linkends="version3" /> access="field|property|nosetter|ClassName"<co id="version4-co" linkends="version4" /> + unsaved-value="null|negative|undefined|value"<co id="version5-co" linkends="version5" /> /></programlisting> <calloutlist> *************** *** 795,798 **** --- 804,816 ---- </para> </callout> + <callout arearefs="version5-co" id="version5"> + <para> + <literal>unsaved-value</literal> (optional - defaults to <literal>undefined</literal>): + A version property value that indicates that an instance is newly instantiated + (unsaved), distinguishing it from transient instances that were saved or loaded + in a previous session. (<literal>undefined</literal> specifies that the identifier + property value should be used.) + </para> + </callout> </calloutlist> *************** *** 819,822 **** --- 837,841 ---- name="propertyName"<co id="timestamp2-co" linkends="timestamp2" /> access="field|property|nosetter|ClassName"<co id="timestamp3-co" linkends="timestamp3" /> + unsaved-value="null|negative|undefined|value"<co id="timestamp4-co" linkends="timestamp4" /> /></programlisting> <calloutlist> *************** *** 838,841 **** --- 857,869 ---- </para> </callout> + <callout arearefs="timestamp4-co" id="timestamp4"> + <para> + <literal>unsaved-value</literal> (optional - defaults to <literal>undefined</literal>): + A timestamp property value that indicates that an instance is newly instantiated + (unsaved), distinguishing it from transient instances that were saved or loaded + in a previous session. (<literal>undefined</literal> specifies that the identifier + property value should be used.) + </para> + </callout> </calloutlist> *************** *** 1091,1095 **** update="true|false"<co id="manytoone6-co" /> insert="true|false"<co id="manytoone7-co" /> ! access="field|property|ClassName"<co id="manytoone8-co" /> /></programlisting> <calloutlist> --- 1119,1125 ---- update="true|false"<co id="manytoone6-co" /> insert="true|false"<co id="manytoone7-co" /> ! property-ref="propertyNameFromAssociatedClass" <co id="manytoone8-co" /> ! access="field|property|ClassName"<co id="manytoone9-co" /> ! unique="true|false" <co id="manytoone10-co" /> /></programlisting> <calloutlist> *************** *** 1134,1137 **** --- 1164,1174 ---- <callout arearefs="manytoone8-co" id="manytoone8"> <para> + <literal>property-ref</literal>: (optional) The name of a property of the associated + class that is joined to this foreign key. If not specified, the primary key of the + associated class is used. + </para> + </callout> + <callout arearefs="manytoone9-co" id="manytoone9"> + <para> <literal>access</literal> (optional - defaults to <literal>property</literal>): The strategy NHibernate should use for *************** *** 1139,1142 **** --- 1176,1185 ---- </para> </callout> + <callout arearefs="manytoone10-co" id="manytoone10"> + <para> + <literal>unique</literal> (optional): Enable the DDL generation of a unique + constraint for the foreign-key column. + </para> + </callout> </calloutlist> <para> *************** *** 1172,1175 **** --- 1215,1245 ---- </listitem> </itemizedlist> + + <para> + A typical <literal>many-to-one</literal> declaration looks as simple as + </para> + + <programlisting><![CDATA[<many-to-one name="Product" class="Product" column="PRODUCT_ID" />]]></programlisting> + + <para> + The <literal>property-ref</literal> attribute should only be used for mapping legacy + data where a foreign key refers to a unique key of the associated table other than + the primary key. This is an ugly relational model. For example, suppose the + <literal>Product</literal> class had a unique serial number, that is not the primary + key. (The <literal>unique</literal> attribute controls NHibernate's DDL generation with + the SchemaExport tool.) + </para> + + <programlisting><![CDATA[<property name="SerialNumber" unique="true" type="String" column="SERIAL_NUMBER" ]]></programlisting> + + <para> + Then the mapping for <literal>OrderItem</literal> might use: + </para> + + <programlisting><![CDATA[<many-to-one name="Product property-ref="SerialNumber" column="PRODUCT_SERIAL_NUMBER" />]]></programlisting> + + <para> + This is certainly not encouraged, however. + </para> </sect2> <sect2 id="mapping-declaration-onetoone"> *************** *** 1186,1190 **** constrained="true|false"<co id="onetoone4-co" /> outer-join="true|false|auto"<co id="onetoone5-co" /> ! access="field|property|ClassName"<co id="onetoone6-co" /> /></programlisting> <calloutlist> --- 1256,1261 ---- constrained="true|false"<co id="onetoone4-co" /> outer-join="true|false|auto"<co id="onetoone5-co" /> ! property-ref="propertyNameFromAssociatedClass" <co id="onetoone6-co" /> ! access="field|property|ClassName"<co id="onetoone7-co" /> /></programlisting> <calloutlist> *************** *** 1223,1226 **** --- 1294,1304 ---- <callout arearefs="onetoone6-co" id="onetoone6"> <para> + <literal>property-ref</literal>: (optional): The name of a property of the associated class + that is joined to the primary key of this class. If not specified, the primary key of + the associated class is used. + </para> + </callout> + <callout arearefs="onetoone7-co" id="onetoone7"> + <para> <literal>access</literal> (optional - defaults to <literal>property</literal>): The strategy NHibernate should use for accessing the property value. *************** *** 1228,1235 **** </callout> </calloutlist> ! <!-- TODO: add details about the new property-ref attribute that Paul added --> </sect2> <sect2 id="mapping-declaration-component"> ! <title>component, dynamic-component</title> <para> --- 1306,1377 ---- </callout> </calloutlist> ! <para> ! There are two varieties of one-to-one associations: ! </para> ! <itemizedlist> ! <listitem> ! <para>primary key associations</para> ! </listitem> ! <listitem> ! <para>unique foreign key associations</para> ! </listitem> ! </itemizedlist> ! ! <para> ! Primary key associations don't need an extra table column; if two rows are related by ! the association then the two table rows share the same primary key value. So if you want ! two objects to be related by a primary key association, you must make sure that they ! are assigned the same identifier value! ! </para> ! ! <para> ! For a primary key association, add the following mappings to <literal>Employee</literal> and ! <literal>Person</literal>, respectively. ! </para> ! ! <programlisting><![CDATA[<one-to-one name="Person" class="Person" />]]></programlisting> ! <programlisting><![CDATA[<one-to-one name="Employee" class="Employee" constrained="true" />]]></programlisting> ! ! <para> ! Now we must ensure that the primary keys of related rows in the PERSON and ! EMPLOYEE table are equal. We use a special identifier generation strategy ! call <literal>foreign</literal>: ! </para> ! ! <programlisting><![CDATA[<class name="Person" table="PERSON"> ! <id name="Id" column="PERSON_ID"> ! <generator class="foreign"> ! <param name="property">Employee</param> ! </generator> ! </id> ! ... ! <one-to-one name="Employee" ! class="Employee" ! constrained="true" /> ! </class>]]></programlisting> ! ! <para> ! A newly saved instance of <literal>Person</literal> is then assigned the same primary ! key value as the <literal>Employee</literal> instance refered with the <literal>Employee</literal> ! property of that <literal>Person</literal>. ! </para> ! ! <para> ! Alternatively, a foreign key with a unique constraint, from <literal>Employee</literal> to ! <literal>Person</literal>, may be expressed as: ! </para> ! ! <programlisting><![CDATA[<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true" />]]></programlisting> ! ! <para> ! And this association may be made bidirectional by adding the following to the ! <literal>Person</literal> mapping: ! </para> ! ! <programlisting><![CDATA[<one-to-one name="Employee" class="Employee" property-ref="Person" />]]></programlisting> ! </sect2> <sect2 id="mapping-declaration-component"> ! <title>component<!--, dynamic-component--></title> <para> *************** *** 1245,1249 **** update="true|false"<co id="component4-co" /> access="field|property|ClassName"<co id="component5-co" /> ! /></programlisting> <calloutlist> <callout arearefs="component1-co" id="component1"> --- 1387,1396 ---- update="true|false"<co id="component4-co" /> access="field|property|ClassName"<co id="component5-co" /> ! > ! <parent ... /> ! <property ... /> ! <many-to-one ... /> ! ... ! <component/></programlisting> <calloutlist> <callout arearefs="component1-co" id="component1"> *************** *** 1277,1280 **** --- 1424,1438 ---- </callout> </calloutlist> + + <para> + The child <literal><property></literal> tags map properties of the + child class to table columns. + </para> + + <para> + The <literal><component></literal> element allows a <literal><parent></literal> + subelement that maps a property of the component class as a reference back to the + containig entity. + </para> </sect2> <sect2 id="mapping-declaration-subclass"> Index: example_parentchild.xml =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/doc/reference/en/modules/example_parentchild.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** example_parentchild.xml 12 Apr 2005 02:45:38 -0000 1.3 --- example_parentchild.xml 4 May 2005 14:48:57 -0000 1.4 *************** *** 277,282 **** that both <literal>Parent</literal> and <literal>Child</literal> have (synthetic) identifier properties of type <literal>System.Int32</literal>. NHibernate will use the identifier property value to determine which of the ! children are new. ! <!-- TODO: add comments about version/timestamp when the build is released --> </para> <para> --- 277,282 ---- that both <literal>Parent</literal> and <literal>Child</literal> have (synthetic) identifier properties of type <literal>System.Int32</literal>. NHibernate will use the identifier property value to determine which of the ! children are new. (You may also use the version or timestamp property ! <!-- TODO: add linkend to manipulatingdata-updating-detached) --> </para> <para> *************** *** 287,294 **** <programlisting><![CDATA[<id name="Id" type="Int64" unsaved-value="0" ]]></programlisting> <para> ! for the <literal>Child</literal> mapping. <!-- ! TODO: not implemented in production build yet ! (There is also an <literal>unsaved-value</literal> attribute ! for version and timestamp property mappings.)--> </para> <para> --- 287,292 ---- <programlisting><![CDATA[<id name="Id" type="Int64" unsaved-value="0" ]]></programlisting> <para> ! for the <literal>Child</literal> mapping. (There is also an <literal>unsaved-value</literal> attribute ! for version and timestamp property mappings.) </para> <para> *************** *** 305,309 **** <para> ! <!-- TODO: discuss use of unsaved-value with version and timestamp --> </para> </sect1> --- 303,337 ---- <para> ! Well, thats all very well for the case of generated identifier, but what about assigned identifiers ! and composite identifiers? This is more difficult, since <literal>unsaved-values</literal> can't ! distinguish between a newly instantiated object (with an identifier assigned by the user) and an object ! loaded in a previous session. In these cases, you will probably need to give NHibernate a hint; either ! </para> ! ! <itemizedlist> ! <listitem> ! <para> ! define <literal>unsaved-value="null"</literal> or <literal>unsaved-value="negative"</literal> or ! <literal>unsaved-value="parsablestring"</literal>on a <literal><version></literal> ! or <literal><timestamp></literal> property mapping for the class. ! </para> ! </listitem> ! <listitem> ! <para> ! set <literal>unsaved-value="none"</literal> and explicitly <literal>Save()</literal> ! newly instantiated children before calling <literal>Update( parent )</literal> ! </para> ! </listitem> ! <listitem> ! <para> ! set <literal>unsaved-value="any"</literal> and explicitly <literal>Update()</literal> ! previously persistent children before calling <literal>Update( parent )</literal> ! </para> ! </listitem> ! </itemizedlist> ! ! <para> ! <literal>none</literal> is the default <literal>unsaved-value</literal> for assigned and composite ! identifiers. </para> </sect1> *************** *** 316,320 **** </para> <para> ! <!-- TODO: describe composite-element --> </para> </sect1> --- 344,352 ---- </para> <para> ! We mentioned an alternative in the first paragraph. None of the above issues exist in the case of ! <literal><composite-element></literal> mappings, which have exactly the semantics of a parent / child ! relationship. Unfortunately, there are two big limitations to composite element classes: composite elements may ! not own collections, and they should not be the child of any entity other than the unique parent. (However, ! they <emphasis>may</emphasis> have a surrogate primary key, using an <literal><idbag></literal> mapping.) </para> </sect1> |