diff options
Diffstat (limited to 'doc/org.eclipse.emf.teneo.doc/tutorials/hibernate/featuremap.html')
-rw-r--r-- | doc/org.eclipse.emf.teneo.doc/tutorials/hibernate/featuremap.html | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/doc/org.eclipse.emf.teneo.doc/tutorials/hibernate/featuremap.html b/doc/org.eclipse.emf.teneo.doc/tutorials/hibernate/featuremap.html new file mode 100644 index 000000000..fbdf4c680 --- /dev/null +++ b/doc/org.eclipse.emf.teneo.doc/tutorials/hibernate/featuremap.html @@ -0,0 +1,547 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<META http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<meta content="Apache Forrest" name="Generator"> +<meta name="Forrest-version" content="0.7"> +<meta name="Forrest-skin-name" content="elver4"> +<style type="text/css"> + /* */ + @import "../skin/tigris.css"; + @import "../skin/quirks.css"; + @import "../skin/inst.css"; + /* */ + </style> +<link media="print" href="../skin/print.css" type="text/css" rel="stylesheet"> +<link href="../skin/forrest.css" type="text/css" rel="stylesheet"> +<link rel="shortcut icon" href="../"> +<script type="text/javascript" src="../skin/tigris.js"></script><script src="../skin/menu.js" language="javascript" type="text/javascript"></script> +<title>FeatureMap/Mixed content support</title> +<meta content="text/css" http-equiv="Content-style-type"> +</head> +<body class="composite" onload="focus()"> +<div id="banner"> +<table width="100%" cellpadding="8" cellspacing="0" border="0"> +<tr> +<td align="left"> +<div> +<a href="http://www.elver.org"><img class="logoImage" alt="Elver Store" src="../images/ELV2.gif"></a> +</div> +<span class="alt">Elver Store</span></td><td align="center"> +<div> +<a href="http://www.elver.org/"><img class="logoImage" alt="Elver" src="../images/empty.gif"></a> +</div> +</td><td valign="top" align="right"> +<div class="right" align="right" id="login"> +<form target="_blank" action="http://www.google.com/search" method="get"> +<select name="as_sitesearch"><option value="">Search...</option><option value="www.elver.org">The elver site</option><option value="">The web</option></select> for + <input size="15" name="as_q" id="query" type="text"><input name="Search" value="Go" type="submit"> +</form> +</div> +</td> +</tr> +</table> +</div> +<div id="toptabs" class="tabs"> +<table border="0" cellspacing="0" cellpadding="4"> +<tr> +<td><a class="base-selected" href="../index.html">Home</a></td><th><a class="base-selected" href="../hibernate/index.html">EMF Hibernate</a></th><td><a class="base-selected" href="../jpox/index.html">EMF JDO/JPOX</a></td><td><a class="base-selected" href="../services/index.html">Services</a></td> +</tr> +</table> +</div> +<table width="100%" border="0" cellpadding="0" cellspacing="0" id="breadcrumbs"> +<tr> +<td></td><td> +<div class="published" align="right"> +<script type="text/javascript" language="JavaScript"><!-- + document.write("Published: " + document.lastModified); + // --></script> +</div> +</td> +</tr> +</table> +<table id="main" width="100%" cellpadding="4" cellspacing="0" border="0"> +<tr valign="top"> +<td style="padding: 0px" width="20%" id="leftcol"> +<table width="100%" class="menuarea" cellspacing="0" cellpadding="0"> +<tr> +<td width="6px" valign="top"> +<table border="0" cellpadding="0" cellspacing="0" class="leftpagemargin"> +<tr> +<td class="subborder trail"> </td> +</tr> +</table> +</td><td class="dialog"> +<div class="menu"> +<div onclick="SwitchMenu('menu_1.1')" id="menu_1.1Title" class="menutitle">Home</div> +<div id="menu_1.1" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/index.html">Introduction</a> +</div> +<div class="menuitem"> +<a href="../hibernate/status.html">Status</a> +</div> +<div class="menuitem"> +<a href="../hibernate/features.html">Features</a> +</div> +<div class="menuitem"> +<a href="../hibernate/overview.html">Overview</a> +</div> +<div class="menuitem"> +<a href="../hibernate/changelog.html">Changelog</a> +</div> +<div class="menuitem"> +<a href="../hibernate/installation.html">Download & Install</a> +</div> +<div class="menuitem"> +<a href="../hibernate/knownissues.html">Known Issues</a> +</div> +<div class="menuitem"> +<a href="../hibernate/quick_tutorial.html">Quick Start</a> +</div> +<div class="menuitem"> +<a href="../hibernate/license.html">License</a> +</div> +</div> +<div onclick="SwitchMenu('menu_1.2')" id="menu_1.2Title" class="menutitle">Library Tutorial</div> +<div id="menu_1.2" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_intro.html">Introduction</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_1.html">Setup Environment</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_2.html">Create and Store EMF Object</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_3.html">Retrieve EMF Objects</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_4.html">Query EMF Objects</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialone/tutorial1_5.html">Using EMF/JPOX Resources</a> +</div> +</div> +<div onclick="SwitchMenu('menu_1.3')" id="menu_1.3Title" class="menutitle">Library Editor Tutorial</div> +<div id="menu_1.3" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/tutorialtwo/tutorial2_intro.html">Introduction</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialtwo/tutorial2_1.html">Initialize the Library Editor</a> +</div> +<div class="menuitem"> +<a href="../hibernate/tutorialtwo/tutorial2_2.html">Run the Library Editor</a> +</div> +</div> +<div onclick="SwitchMenu('menu_1.4')" id="menu_1.4Title" class="menutitle">Details</div> +<div id="menu_1.4" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/dynamic.html">Dynamic EMF Tutorial</a> +</div> +<div class="menuitem"> +<a href="../hibernate/inheritance.html">Inheritance Mapping</a> +</div> +<div class="menuitem"> +<a href="../hibernate/hibernate_relations.html">Modeling Associations</a> +</div> +<div class="menuitem"> +<a href="../hibernate/hbdatastore.html">HbDataStore</a> +</div> +<div class="menuitem"> +<a href="../hibernate/options.html">Options</a> +</div> +<div class="menuitem"> +<a href="../hibernate/hibernate_details.html">EMF - Hibernate Details</a> +</div> +<div class="menuitem"> +<a href="../hibernate/hibernateresources.html">EMF Hibernate Resources</a> +</div> +<div class="menuitem"> +<a href="../hibernate/resource_utility.html">Resource Utility</a> +</div> +</div> +<div onclick="SwitchMenu('menu_1.5')" id="menu_1.5Title" class="menutitle">Annotations</div> +<div id="menu_1.5" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/ejb3_format.html">Format</a> +</div> +<div class="menuitem"> +<a href="../hibernate/ejb3_examples.html">Examples</a> +</div> +<div class="menuitem"> +<a href="../hibernate/ejb3_features.html">EJB3</a> +</div> +<div class="menuitem"> +<a href="../hibernate/custom_annotations.html">Custom</a> +</div> +</div> +<div onclick="SwitchMenu('menu_selected_1.6')" id="menu_selected_1.6Title" class="menutitle">XML Schema</div> +<div id="menu_selected_1.6" class="selectedmenuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/features_details.html">XML Schema Support</a> +</div> +<div class="menuitem"> +<a href="../hibernate/schema_list.html">XML Schema Examples</a> +</div> +<div class="menupage"> +<div class="menupagetitle">Feature Map/Mixed Content</div> +</div> +</div> +<div onclick="SwitchMenu('menu_1.7')" id="menu_1.7Title" class="menutitle">Support</div> +<div id="menu_1.7" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/troubleshooting.html">Troubleshooting</a> +</div> +<div class="menuitem"> +<a href="../hibernate/upgrading.html">Upgrading</a> +</div> +<div class="menuitem"> +<a href="../hibernate/mailinglist.html">Mailinglist</a> +</div> +<div class="menuitem"> +<a href="../hibernate/emfhibsupport.html">EMF/Hibernate Support</a> +</div> +</div> +<div onclick="SwitchMenu('menu_1.8')" id="menu_1.8Title" class="menutitle">Developer</div> +<div id="menu_1.8" class="menuitemgroup"> +<div class="menuitem"> +<a href="../hibernate/svn.html">Subversion</a> +</div> +<div class="menuitem"> +<a href="../hibernate/testcases.html">Test cases</a> +</div> +</div> +</div> +</td> +</tr> +<tr> +<td></td><td> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> +<tr> +<td class="border bottom-left"></td><td class="border bottomborder"></td><td class="border bottom-right"></td> +</tr> +</table> +</td> +</tr> +<tr> +<td colspan="2" height="10"></td> +</tr> +</table> +<table></table> +<table></table> +<div class="strut"> </div> +</td><td> +<div class="content"> +<div id="bodycol"> +<div id="apphead"> +<h2> +<em>FeatureMap/Mixed content support</em> +</h2> +</div> +<div class="abstract">Discusses how FeatureMaps are supported in the persistency solution</div> +<div class="app" id="projecthome"> +<ul class="minitoc"> +<li> +<a href="#FeatureMap+for+derived+features">FeatureMap for derived features</a> +<ul class="minitoc"> +<li> +<a href="#Example+Model">Example Model</a> +</li> +<li> +<a href="#Generated+Code+by+EMF">Generated Code by EMF</a> +</li> +<li> +<a href="#Mapping+to+a+relational+store">Mapping to a relational store</a> +</li> +<li> +<a href="#Using+FeatureMaps">Using FeatureMaps</a> +</li> +</ul> +</li> +<li> +<a href="#FeatureMap+for+Mixed+content">FeatureMap for Mixed content</a> +</li> +<li> +<a href="#Benefits+of+this+approach">Benefits of this approach</a> +</li> +</ul> + +<p>EMF uses Feature Maps in a number of situations, for example to implement XML Schema repeating + model groups or to implement derived features. The Elver persistency layer supports + Feature Maps and generates the required Hibernate mappings. Elver FeatureMap support is hidden + for the developer. The information here is mainly intended to help understand + the created mappings and relational tables.</p> + +<p>See <a class="external" href="http://www.eclipse.org/emf/docs/overviews/FeatureMap.pdf">here</a> for + a description on how EMF uses FeatureMaps to implement derived + features. This page uses a similar example.</p> + +<a name="N1001B"></a><a name="FeatureMap+for+derived+features"></a> +<div class="h3"> +<h3>FeatureMap for derived features</h3> + + +<a name="N10021"></a><a name="Example+Model"></a> +<div class="h4"> +<h4>Example Model</h4> +<p>This section illustrates how a FeatureMap for a derived feature is mapped and + persisted. The model is defined below using an XML Schema. + </p> +<pre class="code"> +<xsd:complexType name="Supplier"> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + <xsd:choice maxOccurs="unbounded" ecore:name="orders"> + <xsd:element name="preferredOrders" type="PurchaseOrder"/> + <xsd:element name="standardOrders" type="PurchaseOrder"/> + <xsd:element name="hardCopyOrderReference" type="xsd:string"/> + <xsd:element name="hardCopyOrderNumber" type="xsd:long"/> + </xsd:choice> + </xsd:sequence> +</xsd:complexType> + </pre> +<p>The xsd:choice with maxOccurs="unbounded" results in a FeatureMap EAttribute with + name orders. In the generated java code this will result in an extra member (named orders) + and accessor methods. </p> +<p>There are 4 derived features. The first two are references to PurchaseOrder, the last two + are primitive/simple type derived features. </p> +</div> + +<a name="N10035"></a><a name="Generated+Code+by+EMF"></a> +<div class="h4"> +<h4>Generated Code by EMF</h4> +<p>EMF will generate the relevant methods to access the derived features. Derived features + will not have java members but will refer to accessor of the FeatureMap EAttribute. For example + the following code shows how the getPreferredOrders uses the getOrders accessor.</p> +<pre class="code"> +public EList getPreferredOrders() { + return ((FeatureMap)getOrders()).list(SimplefeaturemapPackage.eINSTANCE.getSupplier_PreferredOrders()); +} + </pre> +</div> + +<a name="N10043"></a><a name="Mapping+to+a+relational+store"></a> +<div class="h4"> +<h4>Mapping to a relational store</h4> +<p>A FeatureMap is actually an EList with FeatureMap.Entry objects as elements. + A FeatureMap.Entry has two members: 1) a StructuralFeature which defines what type of entry it is, + and 2) the actual value.</p> +<p>For the relational mapping this same structure is + used. For each FeatureMap, Elver will create a separate class mapping. This class mapping + is persisted using the org.elver.store.mapping.elist.FeatureMapEntryTuplizer. + The created class mapping contains a property for each of the possible types in a featuremap. This + ensures that foreign key constraints are created and enforced.</p> +<p>The mapping for the example above is displayed here. First the mapping of the orders property in + Supplier:</p> +<pre class="code"> +<list name="orders" lazy="true" cascade="all,delete-orphan"> + <key update="true"> + <column name="SUPPLIER_ORDERS_ID" not-null="false" unique="false"/> + </key> + <list-index column="SUPPLIER_ORDERS_IDX"/> + <one-to-many entity-name="Supplier_orders"/> +</list> + </pre> +<p>The orders property is mapped as a list with a one-to-many with an entity with a specific name. This name is + generated by Elver and used in the class mapping of the feature map entry:</p> +<pre class="code"> +<class entity-name="Supplier_orders" lazy="false" table="SUPPLIER_ORDERS"> + + <meta attribute="eclass">Supplier</meta> + <id type="long"> + <generator class="native"/> + </id> + <version name="_vn_"/> + + <property name="fme_feature" type="java.lang.String"/> + + <many-to-one name="preferredOrders" entity-name="PurchaseOrder" cascade="all" lazy="false" + insert="true" update="true" not-null="false"> + <column not-null="false" unique="false" name="PURCHASEORDER_PREFERREDORDERS_ID"/> + </many-to-one> + <many-to-one name="standardOrders" entity-name="PurchaseOrder" cascade="all" lazy="false" + insert="true" update="true" not-null="false"> + <column not-null="false" unique="false" name="PURCHASEORDER_STANDARDORDERS_ID"/> + </many-to-one> + <property name="hardCopyOrderReference" type="java.lang.String" lazy="false" not-null="false"/> + <property name="hardCopyOrderNumber" type="long" lazy="false" not-null="false"/> +</class> + </pre> +<p>The feature map entry mapping contains a property for each of the possible feature map entry types. In addition it + contains a property (fme_feature) to store a String to identify the EFeature. + </p> +<p>The persistency logic is hidden for the developer. A FeatureMap which is read from a persistent store will contain + entries which implement the FeatureMap.Entry interface.</p> +</div> + +<a name="N10064"></a><a name="Using+FeatureMaps"></a> +<div class="h4"> +<h4>Using FeatureMaps</h4> +<p>The persisted FeatureMaps can be used in exactly the same way as 'standard' Feature Maps + (See <a class="external" href="http://www.eclipse.org/emf/docs/overviews/FeatureMap.pdf">here</a>). + As an example of this see the code below to create a supplier and set the orders feature.</p> +<pre class="code"> +PurchaseOrder pref1 = factory.createPurchaseOrder(); +pref1.setName("preferred1"); +PurchaseOrder stand1 = factory.createPurchaseOrder(); +stand1.setName("standard1"); +PurchaseOrder stand2 = factory.createPurchaseOrder(); +stand2.setName("standard2"); + +Supplier supplier = factory.createSupplier(); +supplier.setName("supplier"); +supplier.getOrders().add(SimplefeaturemapPackage.eINSTANCE.getSupplier_StandardOrders(), stand1); +supplier.getOrders().add(SimplefeaturemapPackage.eINSTANCE.getSupplier_PreferredOrders(), pref1); +supplier.getOrders().add(SimplefeaturemapPackage.eINSTANCE.getSupplier_HardCopyOrderReference(), "ref1"); +supplier.getOrders().add(SimplefeaturemapPackage.eINSTANCE.getSupplier_HardCopyOrderNumber(), new Long(1002)); +supplier.getOrders().add(SimplefeaturemapPackage.eINSTANCE.getSupplier_StandardOrders(), stand2); + </pre> +<p>The source code below shows how this information can be retrieved using the + derived feature accessors. As is illustrated the persistency extensions are + not visible to the developer:</p> +<pre class="code"> +EList standardList = supplier.getStandardOrders(); // returns the list of standard orders, there are 2 +EList preferredList = supplier.getPreferredOrders(); // returns the list of preferred orders, there is 1 +EList numberList = supplier.getHardCopyOrderNumber(); // returns the list of hard copy numbers +EList referenceList = supplier.getHardCopyOrderReference(); // returns the list hard copy references + +// Will display java.lang.Long +System.err.println(numberList.get(0).getClass().getName()); + +// Will display preferred1 +System.err.println(((PurchaseOrder)preferredList.get(0)).getName()); + +// Retrieve directly through the main featuremap member, +// this is the same purchaseorder as in the previous step +FeatureMap.Entry entry = (FeatureMap.Entry)supplier.getOrders().get(1); +PurchaseOrder referencePO = (PurchaseOrder)entry.getValue(); +// this will also display preferred1 +System.err.println(referencePO.getName()); + </pre> +</div> + +</div> + +<a name="N1007E"></a><a name="FeatureMap+for+Mixed+content"></a> +<div class="h3"> +<h3>FeatureMap for Mixed content</h3> + + +<p>XML Schema allows text data to be mixed with XML nodes, this is called Mixed content. An + example is the xml document below (copied from the + <a class="external" href="http://www.w3.org/TR/xmlschema-0/#mixedContent">XML Schema Primer</a>). In this + XML document text (such as 'Dear Mr.') is mixed with XML nodes (such as <name>Robert Smith</name>).</p> + +<pre class="code"> +<letterBody> +Dear Mr.<name>Robert Smith</name>. +Your order of <quantity>1</quantity> <productName>Baby +Monitor</productName> shipped from our warehouse on +<shipDate>1999-05-21</shipDate>. .... +</letterBody> + </pre> + +<p>The support for mixed content is described in section 3.4 in the + <a class="external" href="http://www.eclipse.org/emf/docs/overviews/XMLSchemaToEcoreMapping.pdf">XML Schema to Ecore Mapping</a>. + In short EMF generates a FeatureMap EAttribute with the name mixed for each complexType with mixed="true". + All elements of the complexType are part of this FeatureMap. + </p> + +<p>For example the xsd below represents the xml document above. For this XML Schema, EMF will generate + a java class with name LetterBody. This class has a FeatureMap member mixed. For the four elements + no java members are generated but only accessor methods which use the mixed FeatureMap.</p> + +<pre class="code"> +<xsd:element name="letterBody"> + <xsd:complexType mixed="true"> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + <xsd:element name="quantity" type="xsd:positiveInteger"/> + <xsd:element name="productName" type="xsd:string"/> + <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/> + <!-- etc. --> + </xsd:sequence> + </xsd:complexType> +</xsd:element> + </pre> + +<p>Mixed content is mapped to a relational store in the same way as the FeatureMap above. The only difference with + the standard FeatureMap mapping a mixed content FeatureMap will contain three fields for storing mixed content: + fme_mixed_text, fme_mixed_cdata and fme_mixed_comment:</p> + +<pre class="code"> +<class entity-name="LetterBodyType_mixed" lazy="false" table="LETTERBODYTYPE_MIXED"> + <meta attribute="eclass">LetterBodyType</meta> + <id type="long"> + <generator class="native"/> + </id> + <version name="_vn_"/> + + <property name="fme_feature" type="java.lang.String"/> + <many-to-one name="salutation" entity-name="SalutationType" cascade="all" lazy="false" + insert="true" update="true" not-null="false"> + <column not-null="false" unique="false" name="SALUTATIONTYPE_SALUTATION_ID"/> + </many-to-one> + <property name="quantity" type="java.math.BigInteger" lazy="false" not-null="false"/> + <property name="productName" type="java.lang.String" lazy="false" not-null="false"/> + <property name="shipDate" type="serializable" lazy="false" not-null="false"/> + <property name="fme_mixed_text" type="java.lang.String"/> + <property name="fme_mixed_cdata" type="java.lang.String"/> + <property name="fme_mixed_comment" type="java.lang.String"/> +</class> + </pre> + +<p> +<em>The current implementation has one limitation: the text, cdata and comment parts of a mixed content can not be longer + than 255 characters, this is the default length for a string column.</em> +</p> + +</div> + +<a name="N100A9"></a><a name="Benefits+of+this+approach"></a> +<div class="h3"> +<h3>Benefits of this approach</h3> + + +<p>The chosen approach has a number of benefits:</p> + +<ul> + +<li>Hidden implementation: The extensions to persist FeatureMaps are completely hidden for the application developer. + He/She can use the standard EMF apis.</li> + +<li>No unnecessary columns: a (nullable) column is only created for the types which + can be present in a FeatureMap.Entry.</li> + +<li>Advanced querying possible: foreign keys are created in the entry table for references + to other classes (tables). This means that it is possible to join tables using advanced + SQL or HQL queries.</li> + +<li>Features such as cascading deletes (containment) or delete restrictions work directly and without + any further extra specifications.</li> + +</ul> + +</div> + +</div> +</div> +</div> +</td> +</tr> +</table> +<div width="100%" id="footer"> +<table width="100%" cellpadding="4" cellspacing="0" border="0"> +<tr> +<td class="footer"><a href="license.html"> + Copyright © 2006 The Elver Project</a> + - All rights reserved. + </td> +</tr> +</table> +</div> +</body> +</html> |