blob: 4f372f77c9317b6b2794f272336ea78dc5edf0fc [file] [log] [blame]
<!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>EMF - Hibernate Integration Details</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">&nbsp;</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 &amp; 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">GMF Editor Tutorial</div>
<div id="menu_1.4" class="menuitemgroup">
<div class="menuitem">
<a href="../hibernate/gmftutorial/tutorial1.html">Introduction</a>
</div>
<div class="menuitem">
<a href="../hibernate/gmftutorial/tutorial2.html">Environment Setup</a>
</div>
<div class="menuitem">
<a href="../hibernate/gmftutorial/tutorial3.html">Running the editor</a>
</div>
</div>
<div onclick="SwitchMenu('menu_selected_1.5')" id="menu_selected_1.5Title" class="menutitle">Details</div>
<div id="menu_selected_1.5" class="selectedmenuitemgroup">
<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="menupage">
<div class="menupagetitle">EMF - Hibernate Details</div>
</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 class="menuitem">
<a href="../hibernate/troubleshooting.html">Troubleshooting</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.6')" id="menu_1.6Title" class="menutitle">Annotations (JPA/EJB3)</div>
<div id="menu_1.6" 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">JPA/EJB3</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.7')" id="menu_1.7Title" class="menutitle">XML Schema</div>
<div id="menu_1.7" class="menuitemgroup">
<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="menuitem">
<a href="../hibernate/featuremap.html">Feature Map/Mixed Content</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.8')" id="menu_1.8Title" class="menutitle">Support</div>
<div id="menu_1.8" class="menuitemgroup">
<div class="menuitem">
<a href="../hibernate/upgrading.html">Upgrading</a>
</div>
<div class="menuitem">
<a href="../hibernate/mailinglist.html">Newsgroup</a>
</div>
<div class="menuitem">
<a href="../hibernate/emfhibsupport.html">EMF/Hibernate Support</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.9')" id="menu_1.9Title" class="menutitle">Developer</div>
<div id="menu_1.9" class="menuitemgroup">
<div class="menuitem">
<a href="../hibernate/svn.html">CVS</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">&nbsp;</div>
</td><td>
<div class="content">
<div id="bodycol">
<div id="apphead">
<h2>
<em>EMF - Hibernate Integration Details</em>
</h2>
</div>
<div class="abstract">Discusses a number of specific implementation and use details of the EMF - Hibernate integration.</div>
<div class="app" id="projecthome">
<ul class="minitoc">
<li>
<a href="#Classloader">Classloader</a>
</li>
<li>
<a href="#Requirements+on+EObjects%3A+InternalEObject">Requirements on EObjects: InternalEObject</a>
</li>
<li>
<a href="#Relational+Validation+and+EObject+persistency">Relational Validation and EObject persistency</a>
</li>
<li>
<a href="#Automatic+creation+of+tables%2FDatabase+Schema">Automatic creation of tables/Database Schema</a>
</li>
<li>
<a href="#orgeneration">Manual Generation of OR Mapping</a>
</li>
<li>
<a href="#escaping">Escaping of table and column names</a>
</li>
<li>
<a href="#Lazy+loading%2Ffetching%2C+Proxy">Lazy loading/fetching, Proxy</a>
</li>
<li>
<a href="#Automatic+creation+of+TypeDef+for+EDataType">Automatic creation of TypeDef for EDataType</a>
</li>
<li>
<a href="#Client-Server+scenario%3A+requires+explicitly+modelled+id+and+version+properties">Client-Server scenario: requires explicitly modelled id and version properties</a>
</li>
<li>
<a href="#Default+ID+Feature+Name">Default ID Feature Name</a>
</li>
<li>
<a href="#Synthetic+ID+and+Version+properties">Synthetic ID and Version properties</a>
</li>
<li>
<a href="#cutpaste">Move an EObject between EContainers or support cut and paste in the EMF editor</a>
</li>
<li>
<a href="#Validation">Validation</a>
</li>
<li>
<a href="#Default+cacheprovider+is+org.hibernate.cache.HashtableCacheProvider">Default cacheprovider is org.hibernate.cache.HashtableCacheProvider</a>
</li>
</ul>
<a name="N10011"></a><a name="Classloader"></a>
<div class="h3">
<h3>Classloader</h3>
<p>Teneo performs explicit classloading in specific locations. It is possible to set the classloader which is being
user by Teneo. This can be done through the org.eclipse.emf.teneo.ClassLoaderResolver class. In this class you can
register a org.eclipse.emf.teneo.classloader.ClassLoaderStrategy. The registered ClassLoaderStrategy is used by
Teneo to explicitly load classes.</p>
</div>
<a name="N1001A"></a><a name="Requirements+on+EObjects%3A+InternalEObject"></a>
<div class="h3">
<h3>Requirements on EObjects: InternalEObject</h3>
<p>The EMF Hibernate persistency layer only requires that the persisted objects implement
the org.eclipse.emf.ecore.InternalEObject interface.</p>
</div>
<a name="N10023"></a><a name="Relational+Validation+and+EObject+persistency"></a>
<div class="h3">
<h3>Relational Validation and EObject persistency</h3>
<p>When an object is made persistent by session.save() then at
that moment also constraints, such as nullable fields, are checked. So when
calling the session.save method the passed EObject should be valid.</p>
</div>
<a name="N1002D"></a><a name="Automatic+creation+of+tables%2FDatabase+Schema"></a>
<div class="h3">
<h3>Automatic creation of tables/Database Schema</h3>
<p>The EMF Hibernate persistency layer will automatically update the database schema
when a new SessionFactory is registered. The Hibernate class org.hibernate.tool.hbm2ddl.SchemaUpdate class is used for
this purpose.</p>
<p>An <a href="hbdatastore.html#options">option</a> can be used to control if the database schema should be updated when a new HbDataStore
is created.</p>
</div>
<a name="N1003D"></a><a name="orgeneration"></a>
<div class="h3">
<h3>Manual Generation of OR Mapping</h3>
<p>Standard Teneo will automatically map the model to Hibernate when a datastore is initialized. However, it can sometimes make sense to manually
adapt the mapping or use a specific mapping file. For this purpose Teneo also allows you to manually generate the mapping file. To do this right
click on one or more .ecore files and choose the relevant option in the Teneo submenu.</p>
<p>
</p>
<div align="center">
<img class="figure" alt="Manual generation of hibernate or mapping" src="images/elver_menu.gif"></div>
<p>The hibernate.hbm.xml is created in the folder of the selected .ecore file. To direct Teneo to use this mapping file you
need to do the following:</p>
<ol>
<li>Copy the hibernate.hbm.xml to the generated EPackage source tree and let it be copied to the output directory/destination when building.</li>
<li>Pass the following option: PersistenceOptions.USE_MAPPING_FILE with the value "true" to the HbDataStore.</li>
</ol>
<p>
<strong>Note:</strong> the generation of the hibernate.hbm.xml will only work if the org.eclipse.emf.teneo.hibernate.runtime plugin has been added to the
dependencies of the projects of the selected .ecore files.</p>
</div>
<a name="N1005D"></a><a name="escaping"></a>
<div class="h3">
<h3>Escaping of table and column names</h3>
<p>Teneo will escape table and column names of primitive types. Escaping is done by surrounding the name with backtics (`).</p>
<p>Note that:</p>
<ul>
<li>Join table names are not escaped: Hibernate will in some cases automatically create a table to store the contents of a collection,
for example the contents of a list with primitive types. Hibernate will not automatically escape this name. To escape such a join table you
need to add a JoinTable annotation with an escaped name or a non-keyword name.</li>
<li>Teneo will not escape column names of manually specified Column annotations</li>
</ul>
</div>
<a name="N10072"></a><a name="Lazy+loading%2Ffetching%2C+Proxy"></a>
<div class="h3">
<h3>Lazy loading/fetching, Proxy</h3>
<p>The Hibernate integration does not make use of the Hibernate Proxy.</p>
<p>Primitive features and single refererences are eagerly loaded. ELists are
lazily loaded. In the future probably also single-references will be lazily loaded.</p>
</div>
<a name="N1007E"></a><a name="Automatic+creation+of+TypeDef+for+EDataType"></a>
<div class="h3">
<h3>Automatic creation of TypeDef for EDataType</h3>
<p>When you define an EDataType in your EPackage Teneo will automatically map this EDataType to a TypeDef if the instanceClass of
the EDataType can not be handled by native Hibernate.</p>
<p>The TypeDef will make use of the
UserType org.eclipse.emf.teneo.hibernate.mapping.DefaultToStringUserType. This user type persists the value in a single varchar column.
This means that the EDataType needs to be convertable from/to a String. EMF will generate the appropriate methods in the generated
EFactory for your EPackage. Many times EMF will throw an UnsupportedOperationException. You need to manually change this code to convert
your type correctly from and to a String.
</p>
</div>
<a name="N1008A"></a><a name="Client-Server+scenario%3A+requires+explicitly+modelled+id+and+version+properties"></a>
<div class="h3">
<h3>Client-Server scenario: requires explicitly modelled id and version properties</h3>
<p>When Teneo detects that a certain type does not have an id or version annotated property then
it will add these automatically (see next point). The synthetic id and version are hidden for the developer. However, the synthetic id
and version will not work when objects are (de)serialized for example in a client-server situation. In this case you
need to explicitly model an id and a version property and annotate them as such using jpa annotations.
</p>
</div>
<a name="N10093"></a><a name="Default+ID+Feature+Name"></a>
<div class="h3">
<h3>Default ID Feature Name</h3>
<p>When Teneo searches for the id-feature of an eclass it searches for an efeature with the @id annotation. If no efeature with such an annotation
can be found Teneo will search for a feature with the name specified in the PersistenceOptions.DEFAULT_ID_FEATURE_NAME option
(see persistence options <a href="options.html">here</a>). A possible use to set this option to "id" and add a feature with
the name "id" to each eclass. This "id" feature is then automatically used as the persistence identifier by Teneo.
</p>
</div>
<a name="N100A0"></a><a name="Synthetic+ID+and+Version+properties"></a>
<div class="h3">
<h3>Synthetic ID and Version properties</h3>
<p>When Teneo detects that a certain type does not have an id or version annotated property then
it will add these automatically. The synthetic id and version are hidden for the developer. You can
retrieve the hidden synthetic id or version through the class org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler.
You can prevent the automatic adding of a synthetic version property by setting the PersistenceOptions.ALWAYS_VERSION
to false, see <a href="options.html">here</a>. If this property is false then only efeatures with a version annotation are
translated into a version mapping.</p>
<p>Synthetic id and version use object equality (==), this means that synthetic id and version will not
work if objects are transferred to other systems and back (for example in case of client-server communication).</p>
</div>
<a name="N100B0"></a><a name="cutpaste"></a>
<div class="h3">
<h3>Move an EObject between EContainers or support cut and paste in the EMF editor</h3>
<p>In the standard approach it is not possible to move an EObject from one containment relation to another containment relation. A move
between containment relations corresponds to a cut and paste in the EMF editor. The reason is that Teneo will
specify an orphan-delete cascade for a containment relation. This has as a consequence that Hibernate will throw
an exception (deleted object would be re-saved by cascade, remove deleted object from associations) when you move an EObject from its container to another container.
See <a class="external" href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-785">here</a> for a description.</p>
<p>
<em>Solution:</em> as a solution you can prevent the orphan-delete from being set as the cascade style, by specifying
an annotation on the relevant EReference features or by setting the global runtime property PersistenceOptions.SET_CASCADE_ALL_ON_CONTAINMENT
to false (see <a href="options.html">here</a>). As an example of the first approach:</p>
<pre class="code">
&lt;xsd:element maxOccurs="unbounded" minOccurs="0" name="writers" type="lib:Writer"&gt;
&lt;xsd:annotation&gt;
&lt;xsd:appinfo source="teneo.jpa"&gt;@OneToMany(cascade={MERGE,PERSIST,REFRESH,REMOVE})&lt;/xsd:appinfo&gt;
&lt;/xsd:annotation&gt;
&lt;/xsd:element&gt;
</pre>
<p>This annotation means that cascading deletes are still enforced but a child (the Writer) can exist without its
parent (the Library).</p>
<p>When this annotation is used in the context of a Hibernate Resource then when an EObject is removed from
its container then it will also be removed from the resource and from the database. However, when you set this
annotation and not work with Hibernate Resources then the removed EObject is not removed from the database and will
be present without a container!</p>
</div>
<a name="N100D1"></a><a name="Validation"></a>
<div class="h3">
<h3>Validation</h3>
<p>When storing and retrieving EMF objects from a Hibernate store it is not required to work with a
EMF type Resource. However the standard EMF validator checks if every EObject is
present in an EMF resource and that all referenced EObjects are in the same resource. So, if
this standard validator is used unnecessary errors are thrown.
</p>
<p>To prevent this situation you can register your own validator which does not perform this resource check.
See the example here below.
</p>
<p>
Validators are registered using a call to put method of the EValidator.Registry.INSTANCE object.
</p>
<pre class="code">
public class MyValidator extends EObjectValidator
{
/**
* Overrides the method from the superclass to prevent this check because it
* is not required in the context of a hibernate store. Note that this assumes that
* an object and its references are all stored in the same hibernate database.
*/
public boolean validate_EveryReferenceIsContained(EObject eObject, DiagnosticChain diagnostics, Map context)
{
return true;
}
}
</pre>
</div>
<a name="N100E5"></a><a name="Default+cacheprovider+is+org.hibernate.cache.HashtableCacheProvider"></a>
<div class="h3">
<h3>Default cacheprovider is org.hibernate.cache.HashtableCacheProvider</h3>
<p>Default cacheprovider has been set to org.hibernate.cache.HashtableCacheProvider because of ehcache issues which occur when using
ehcache with the default values.</p>
<p>Encountered error message was:
<em>Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() between repeated calls to buildSessionFactory. Consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider. Error from ehcache was: Cannot parseConfiguration CacheManager. Attempt to create a new instance of CacheManager using the diskStorePath "/tmp" which is already used by an existing CacheManager. The source of the configuration was classpath.</em>
</p>
<p>The HashtableCacheProvider is not for production use. You can override this default setting by setting the hibernate.cache.provider_class property with the cache provider class you want to use.
</p>
</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 &copy; 2007 The Elver Project</a>
- All rights reserved.
</td>
</tr>
</table>
</div>
</body>
</html>