diff --git a/Doc/course.xml b/Doc/course.xml index c3f83e8324213513e24a72cfcf580fa17771e652..127b6558889dbe2a897a0ac17e77406fadd0456e 100644 --- a/Doc/course.xml +++ b/Doc/course.xml @@ -17345,20 +17345,167 @@ public class CreditCard extends BillingDetails { linkend="tpcNotNullCardType"/> and <coref linkend="tpcNotNullexpiration"/>.</para> - <para>Abbildung: Tiefe Vererbungshierarchie</para> - <section xml:id="joinedSubclassRetrieve"> <title>Retrieving Objects</title> - <para>On the database server side object retrieval becomes a more - expensive operation:</para> + <para>On the database server side object retrieval results in a + more expensive operation. A query for the root class + <classname>inherit.joined.v1.BillingDetails</classname> <coref + linkend="joinedQueryBillingDetails"/> of our inheritance hierarchy + results in joining all three tables <code>BillingDetails</code> + <coref linkend="joinFromBillingDetails"/>, + <code>BankAccount</code> <coref linkend="joinFromBankAccount"/> + and <code>CreditCard</code> <coref + linkend="joinFromCreditCard"/>:</para> + + <informaltable border="1"> + <colgroup width="6%"/> + + <colgroup width="94%"/> + + <tr> + <td valign="top"><emphasis role="bold">Java</emphasis></td> + + <td valign="top"><programlisting>package inherit.joined.v1; +... +public class RetrieveAll { +... + final Query searchBilling = session.createQuery("<emphasis role="bold">from inherit.tpc.v1.BillingDetails</emphasis>" <co + xml:id="joinedQueryBillingDetails"/>); +...</programlisting></td> + </tr> + + <tr> + <td valign="top"><emphasis role="bold">Sql</emphasis></td> + + <td><programlisting continuation="continues">Hibernate: + select + billingdet0_.id as id0_, + billingdet0_.created as created0_, + billingdet0_.number as number0_, + billingdet0_1_.bankName as bankName1_, + billingdet0_1_.swiftcode as swiftcode1_, + billingdet0_2_.cardType as cardType2_, + billingdet0_2_.expiration as expiration2_, + case + when billingdet0_1_.id is not null then 1 + when billingdet0_2_.id is not null then 2 + when billingdet0_.id is not null then 0 + end as clazz_ + from + <emphasis role="bold">BillingDetails</emphasis> billingdet0_ <co + xml:id="joinFromBillingDetails"/> + left outer join + <emphasis role="bold">BankAccount</emphasis> billingdet0_1_ <co + xml:id="joinFromBankAccount"/> + on billingdet0_.id=billingdet0_1_.id + left outer join + <emphasis role="bold">CreditCard</emphasis> billingdet0_2_ <co + xml:id="joinFromCreditCard"/> + on billingdet0_.id=billingdet0_2_.id </programlisting></td> + </tr> + </informaltable> <qandaset role="exercise"> <qandadiv> <qandaentry> <question> - <para/> + <para>Explain all integrity constraints of the Hibernate + generated schema. Is it able to implement the correct + constraints on database level corresponding to the + inheritance related <trademark + xlink:href="http://www.oracle.com/us/technologies/java">Java</trademark> + objects? On contrary: Are there possible database states + which do not correspond to the domain model's object + constraints? </para> </question> + + <answer> + <para>We take a look to the database schema:</para> + + <programlisting>CREATE TABLE BillingDetails ( + id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY <co + linkends="inheritJoinSqlJava-1" + xml:id="inheritJoinSqlJava-1-co"/>, + created datetime NOT NULL, + number varchar(32) NOT NULL +); +CREATE TABLE CreditCard ( + id bigint(20) NOT NULL PRIMARY KEY <co linkends="inheritJoinSqlJava-2" + xml:id="inheritJoinSqlJava-2-co"/> REFERENCES <co + linkends="inheritJoinSqlJava-3" + xml:id="inheritJoinSqlJava-3-co"/> BillingDetails, + cardType int(11) NOT NULL, + expiration datetime NOT NULL +); +CREATE TABLE BankAccount ( + id bigint(20) NOT NULL PRIMARY KEY <co linkends="inheritJoinSqlJava-4" + xml:id="inheritJoinSqlJava-4-co"/> REFERENCES <co + linkends="inheritJoinSqlJava-4" + xml:id="inheritJoinSqlJava-5-co"/> BillingDetails, + bankName varchar(255) NOT NULL, + swiftcode varchar(255) NOT NULL +);</programlisting> + + <calloutlist> + <callout arearefs="inheritJoinSqlJava-1-co" + xml:id="inheritJoinSqlJava-1"> + <para>The table implementing the root class + <classname>inherit.joined.v1.BillingDetails</classname> + of the inheritance hierarchy will be referenced both + by <code>CreditCard</code> and + <code>BankAccount</code> datasets and thus requires a + key to become addressable. Moreover the corresponding + <classname>inherit.joined.v1.BillingDetails</classname> + class requires this attribute to be the primary key + anyway.</para> + </callout> + + <callout arearefs="inheritJoinSqlJava-2-co" + xml:id="inheritJoinSqlJava-2"> + <para>Each <code>CreditCard</code> portion of + attributes belongs to exactly one + <code>BillingDetails</code> instance and hence the id + must be unique.</para> + </callout> + + <callout arearefs="inheritJoinSqlJava-3-co" + xml:id="inheritJoinSqlJava-3"> + <para>As stated in <coref + linkend="inheritJoinSqlJava-2-co"/> each + <code>CreditCard</code> dataset must refer to its + parent <code>BillingDetails</code> instance.</para> + </callout> + + <callout arearefs="inheritJoinSqlJava-4-co inheritJoinSqlJava-5-co" + xml:id="inheritJoinSqlJava-4"> + <para>These constraints likewise describe <coref + linkend="inheritJoinSqlJava-2"/> and <coref + linkend="inheritJoinSqlJava-3"/> for + <code>BankAccount</code> datasets.</para> + </callout> + </calloutlist> + + <para>Of course the NOT NULL constraints implement their + counterpart properties in the corresponding <trademark + xlink:href="http://www.oracle.com/us/technologies/java">Java</trademark> + objects.</para> + + <para>The mapping does not cover one important integrity + constraint of our domain model. The base class + <classname>inherit.joined.v1.BillingDetails</classname> is + abstract. Thus each entry in the database must refer + either to a + <classname>inherit.joined.v1.CreditCard</classname> or a + <classname>inherit.joined.v1.BankAccount</classname> + instance. But the above database schema allows for + datasets in <code>BillingDetails</code> not being + referenced at all.</para> + + <para>So the current database schema actually refers to a + domain model having a concrete base class + <code>BillingDetails</code>.</para> + </answer> </qandaentry> </qandadiv> </qandaset>