Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EMF/Teneo/EclipseLink/Understanding JPA Mapping"

m (Understanding JPA Mapping for EMF =)
(Mapping in XML)
Line 10: Line 10:
  
 
If you do not include this property Teneo will not be enabled and EclipseLink will fail to initialize your persistence unit and exit with an exception.
 
If you do not include this property Teneo will not be enabled and EclipseLink will fail to initialize your persistence unit and exit with an exception.
 +
 +
== Naming Entities ==
 +
 +
EMF code generation produces interfaces and implementation ("impl") classes but JPA Entities must be impl classes.  An Entity's name defaults to the short name of the class but this can lead to some awkwardness in JPQL queries.  For example, the expanded Library example includes BookImpl and the interface Book.
 +
 +
<source lang="java">
 +
public class BookImpl extends IdentifiableImpl implements Book {
 +
</source>
 +
 +
With the default Entity name "BookImp" we would be required to use this name in JPQL.  For example, '''"Select b from BookImpl b where b.title='Moby Dick'"'''.  The use of BookImpl in JPQL isn't very natural.
 +
 +
We can solve this by defining the Entity name of the BookImpl class to be Book.
 +
 +
<source lang="xml">
 +
    <entity name="Book" class="BookImpl" access="FIELD">
 +
        ...
 +
</source>
 +
 +
With this declaration we can write the query '''"Select b from Book b where b.title='Moby Dick'"''' which will return instances of BookImpl.
  
 
== Mapping in XML ==
 
== Mapping in XML ==

Revision as of 16:47, 7 July 2009

Understanding JPA Mapping of EMF with Teneo EclipseLink

Enabling Teneo

EMF does not conform to the requirements for Entities defined in the JPA 1.0 specification. Coping with this mismatch is the principal focus of the runtime component of Teneo's EclipseLink JPA support. To enable Teneo's EMF support you must include the following property for each persistence unit in your persistence.xml:

<property name="eclipselink.session.customizer" value="org.eclipse.emf.teneo.eclipselink.EmfSessionCustomizer"/>

If you do not include this property Teneo will not be enabled and EclipseLink will fail to initialize your persistence unit and exit with an exception.

Naming Entities

EMF code generation produces interfaces and implementation ("impl") classes but JPA Entities must be impl classes. An Entity's name defaults to the short name of the class but this can lead to some awkwardness in JPQL queries. For example, the expanded Library example includes BookImpl and the interface Book.

public class BookImpl extends IdentifiableImpl implements Book {

With the default Entity name "BookImp" we would be required to use this name in JPQL. For example, "Select b from BookImpl b where b.title='Moby Dick'". The use of BookImpl in JPQL isn't very natural.

We can solve this by defining the Entity name of the BookImpl class to be Book.

    <entity name="Book" class="BookImpl" access="FIELD">
        ...

With this declaration we can write the query "Select b from Book b where b.title='Moby Dick'" which will return instances of BookImpl.

Mapping in XML

Because you may regenerate classes from your Ecore model, you should do all mapping in XML. The use of annotations is not recommended as they will be lost if you regenerate. You can certainly use them but remember you have been warned.

Field or Property Access

Regardless of what access type you specify, Teneo will adjust your mappings to use a hybrid access approach. To take advantage of lazy initialization, Teneo will configure property access when reading an attribute from a Enity. But to avoid firing events when constructing an object, Teneo wil configure direct field access when setting an attribute.

OneToMany

In JPA 1.0 OneToMany relationships require a 'back reference' from the target of the relationship (i.e., the objects in the collection) back to the owner of the relationship. The back reference should be mapped as a ManyToOne. The back reference mapping varies depending upon whether the many are contained.

OneToMany without EMF Containment

When dealing with a non-containment relationship, the target of the OneToMany mapping will need an attribute holding the back reference which is mapped with a ManyToOne. In the extended Library example, WriterImpl has a non-containment OneToMany relationship with BookImpl. Note that the mapped-by is "author", an attribute of BookImpl that is mapped as a ManyToOne back to WriterImpl.

WriterImpl's books mapping:

   <entity name="Writer" class="WriterImpl">
         ...
         <one-to-many name="books" mapped-by="author" target-entity="BookImpl">
          ...

BookImpl's author mapping:

    <entity name="Book" class="BookImpl" access="FIELD">
        ...
        <many-to-one name="author" target-entity="WriterImpl">
        ...

OneToMany with EMF Containment

In the case of an EMF containment relationship, the back reference to the owning object is maintained in the eContainer attribute. In the Library example, a LibraryImpl has an EList of WriterImpls which in JPA is mapped as a OneToMany. Because LibraryImpl->WriterImpl is a containment relationship, each WriterImpl's eContainer reference will point to it's owning LibraryImpl.

LibraryImpl's writers mapping:

    <entity name="Library" class="LibraryImpl">
        ...
	<one-to-many name="writers" target-entity="WriterImpl" mapped-by="eContainer">
        ...

WriterImpl's back reference to it's eContainer:

    <entity name="Writer" class="WriterImpl">
        ...
        <many-to-one name="eContainer" target-entity="LibraryImpl">
        ...

Back to the top