Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

CDO/Hibernate Store/Model Relational Mapping


The CDO Hibernate Store can use Teneo for the Model Relational mapping. Teneo generates a mapping for Hibernate on the basis of the ecore model and optional JPA annotations. JPA annotations can be specified directly in the model or in a separate xml.

JPA annotations allow a developer to do many things, some of the possibilities: determine the naming of columns and tables, enables or prevents join tables, specify embedded components, specify the name of foreign key columns, the inheritance mapping, if an index column is used, the sorting of a collection, enable external references, etc. etc.

Teneo supports all JPA annotations and many Hibernate extensions.

The JPA specification contains a description of each annotation, download it from here (click on the first button, then at a later page select the pdf with the word persistence).

JPA Annotations with a TYPE target can be used for EMF EClasses, annotations with METHOD and FIELD targets can be used for EStructuralFeatures. Note: JPA annotations relevant for a non-reference type java member can also be set on an EDataType.

Annotations Format

The Teneo documentation has a detailed description of the format in which annotations can be specified. The main points are summarized here:

Teneo allows two ways to specify EJB3/JPA-like annotations:

  1. using the java annotations syntax in EAnnotations (ecore and xsd) (examples)
  2. a separate xml document (examples).


Annotations in the model itself (xsd or ecore)

JPA Annotations are set in the model using the EMF EAnnotation. The EAnnotations should adhere to the following format:

  • The source must be: teneo.jpa. You can also configure your own annotation source, see Teneo documentation for details.
  • The key must be: appinfo or value

The page: here contains examples of JPA eannotations in Ecore or in a XML Schema file.

JPA Annotations in XSD, some examples

This annotation sets the inheritance mapping strategy for the Address to joined:

<xsd:complexType name="Address" abstract="true">
	<xsd:annotation>
		<xsd:appinfo source="teneo.jpa">@Inheritance(strategy=JOINED)</xsd:appinfo>
	</xsd:annotation>
 	<xsd:sequence>
		<xsd:element name="name" type="xsd:string"/>
	</xsd:sequence>
</xsd:complexType>

The following annotation specifies that the association does not need an index column:

<xsd:element name="containedItem" type="this:ContainedItem" maxOccurs="unbounded">
	<xsd:annotation>
		<xsd:appinfo source="teneo.jpa">@OneToMany(indexed=false)</xsd:appinfo>
	</xsd:annotation>
</xsd:element>

Setting JPA Annotations using the Ecore Model Editor

To set an annotation in the ecore model using the Ecore Model Editor do the following:

  1. open the model in the editor
  2. right click on the model element (EClass, EStructuralFeature, etc.) on which you want to set a JPA annotation
  3. do: New Child > EAnnotation
  4. check in the properties view, there are two fields for the new EAnnotation: references and source. Set source to: teneo.jpa
  5. right click on the new EAnnotation in the ecore model editor and do: New Child > Details Entry
  6. click on the new detail entry, the properties view shows a key and value field. Enter the word 'value' in the key field and in the value field enter your annotation, for example: @Id or @Basic. Just as you would set it in Java.

JPA Annotations in XML

JPA annotations can also be specified in a separate xml file. The advantage of this approach is that you can annotate models which are not in your control. The separate annotated xml means that the original model file does not need to be changed. You can even annotate the Ecore model itself!

The xsd for the XML annotations can be downloaded here. The xsd shows that it is possible to specify annotations on EPackage, EClass, EAttribute, EReference and EDataType level. In addition there is a special property element which combines the annotations for EAttribute and EReference. The property tag is a convenience tag which can be used to in place of both an EAttribute and an EReference tag.

A number of examples of annotations in xml can be found here.

When using Teneo within CDO then the location of the annotations xml (a class path location) should be set in the cdo-server.xml using the option: PersistenceOptions.PERSISTENCE_XML. The location should be a resource/class path. When using Teneo stand alone this same option should be used, but then it should be passed to the HbDataStore.setProperties(..) method.

To make the annotations xml file available to the CDO server at runtime you have to place the annotations xml in a separate plugin, see here for more information.

JPA Annotations in the example projects

The CDO Hibernate Store documentation makes use of a number of example projects. The example projects also make use of in-model annotations as well as annotations in a separate XML file.

To see the in-model JPA annotations go to the org.eclipse.emf.cdo.examples.company project and then the model folder. Open the company.ecore file in an ecore model editor, navigate through the model:

  • The Product.name EStructuralFeature has an @Id annotation, specifying that this feature is the primary key.
  • The Order EClass has an annotation to set the entity name (this name should be used in HQL queries).
  • The OrderAddress EClass has a more complex annotation to prevent name clashes when creating the relational schema.

The examples also make use of extra annotations in an annotations.xml. To see this open the org.eclipse.emf.cdo.examples.hibernate.server project and the META-INF folder. There you will find an annotations xml file. The classpath of this file is specified in the cdo-server.xml which you can find the config folder of that same project.

To ensure that the annotations xml file is visible for Teneo/Hibernate a dependency has been set to the org.eclipse.emf.cdo.server.hibernate.teneo (see the MANIFEST.MF).

Generating the mapping, manually changing it and then use the manual mapping

The preferred way of controlling the mapping to hibernate is to use JPA annotations in the model or XML. It is however also possible to generate a mapping, change it manually and then use that manual mapping instead of the generated one. To do this the following steps have to be done:

  1. generate a mapping (see below on how to do that) and store it in a file
  2. place this file in a location in the server side plugin, preferably the config location of the cdo-server config file.
  3. Follow the steps outlined in Additional Hibernate or other Config files (set build.properties, set Eclipse buddy policy etc.)
  4. then change the cdo-server.xml, the mapping provider should be changed to the file mapping provider and the location of the mapping file should be set:
<mappingProvider type="file">
	<mappingFile location="generated_hbm.xml"/>
</mappingProvider>
  1. also make sure that the epackages handled in the mapping file are set as initial packages, if not an exception is thrown. This is done inside the cdo-server.xml file like this:
<initialPackage nsURI="http://www.eclipse.org/emf/CDO/examples/company/1.0.0"/>


The examples projects contain configuration/code showing how to generate the mapping and use it in the CDO Server.

To generate a mapping look at the org.eclipse.emf.cdo.examples.hibernate.client project and then GenerateHBMTest class. This class shows how the mapping can be generated:

    // create a properties
    final Properties props = new Properties();
    // this property should normally be set like this:
    props.put(PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT, "PERSIST,MERGE"); //$NON-NLS-1$
 
    // add some demo properties
    props.put(PersistenceOptions.INHERITANCE_MAPPING, "JOINED"); //$NON-NLS-1$
    props.put(PersistenceOptions.ADD_INDEX_FOR_FOREIGN_KEY, "true"); //$NON-NLS-1$
 
    // get the epackages
    final EPackage[] ePackages = new EPackage[] { CompanyPackage.eINSTANCE };
 
    // generate the mapping
    final CDOMappingGenerator mappingGenerator = new CDOMappingGenerator();
    final String mapping = mappingGenerator.generateMapping(ePackages, props);
 
    // show it somewhere....
    // then store the hbm somewhere in a file and change it manually
    System.err.println(mapping);

Note, the above code has dependencies on the following plugins:

  • org.eclipse.emf.cdo.server.hibernate.teneo
  • org.eclipse.emf.teneo
  • org.apache.commons.logging

See the MANIFEST.MF of the client examples project. Normally a client-side plugin would not have these dependencies but these are only needed as the GenerateHBMTest class is placed in the same plugin.

The generated mapping file has been placed in the org.eclipse.emf.cdo.examples.hibernate.server examples project in the config folder. To make use of it open the cdo-server.xml (in the META-INF folder) and uncomment the file mapping provider (in the bottom) and comment the teneo mapping provider.

Then when you restart the CDO server the mapping file is used.

Teneo JPA Annotations Details

For more information on how to set JPA annotations in your model visit the Teneo Model Relation Mapping Overview page.

Teneo Extensions

Teneo has an extension mechanism which makes it possible to replace core Teneo mapping classes with your own implementations. This extension mechanism can also be used with CDO. The setup makes use of the cdo-server.xml. This section only describes the setup in the context of CDO, for information on how to implement extensions see Teneo wiki.

The org.eclipse.emf.cdo.examples.hibernate.server project contains an example of configuring an extension. A summary of the steps:

  • implement the extension class. Normally you should extend a Teneo class. However there are already a number of extensions re-implemented for CDO. These are located in the org.eclipse.emf.cdo.server.hibernate.teneo plugin. So it is quite possible that you need to extend one of the classes in that plugin.
  • ensure that the class is visible to the CDO Hibernate store plugins. This is done by:
    • exporting the package containing your extension classes, this is specified in the MANIFEST.MF file
    • set the Eclipse-BuddyPolicy in your plugin (in the MANIFEST.MF) as such:
Eclipse-RegisterBuddy: org.eclipse.emf.cdo.server.hibernate, org.eclipse.emf.cdo.server.hibernate.teneo
  • specify the extension in the cdo-server.xml. This is done by adding extension tags to the mappingProvider tag in the cdo-server.xml.
<mappingProvider type="teneo">
	<extension name="org.eclipse.emf.teneo.annotations.mapper.EFeatureAnnotator" 
		value="org.eclipse.emf.cdo.examples.hibernate.server.CDOExampleEFeatureAnnotator"/>
</mappingProvider>



Wikis: CDO | Net4j | EMF | Eclipse

Back to the top