Difference between revisions of "EclipseLink/Examples/JPA/Extensible"

From Eclipsepedia

Jump to: navigation, search
(Flex Extensions)
 
(5 intermediate revisions by one user not shown)
Line 9: Line 9:
 
== Extensible Entities Example ==
 
== Extensible Entities Example ==
  
This example illustrates how EclipseLink 2.2 can be used to build a domain model that allows addition 'extension' properties, relationships, and types to added and used in the application.  
+
This example illustrates how EclipseLink 2.2 can be used to build a domain model that allows addition 'extension' properties, relationships, and types to added and used in the application. This approach to extensible properties includes storing the definition of the extension and limiting the entity to allowing only extension values that have been defined. This will also allow greater sharing of extension information between application instances and exposing the extended properties in the JPA 2.0 metamodel.
  
 
''NOTE: This functionality is being formalized into new features for [[EclipseLink/Development/Indigo|EclipseLink Indigo (2.3)]] in its [[EclipseLink/DesignDocs/Extensibility|Extensibility]] features.''
 
''NOTE: This functionality is being formalized into new features for [[EclipseLink/Development/Indigo|EclipseLink Indigo (2.3)]] in its [[EclipseLink/DesignDocs/Extensibility|Extensibility]] features.''
Line 16: Line 16:
  
 
The example is being developed within the trunk of EclipseLink:
 
The example is being developed within the trunk of EclipseLink:
* SVN: [http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/jpa.employee/eclipselink.example.jpa.employee.extensions/]
+
* SVN: [http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/jpa.employee/eclipselink.example.jpa.employee.extensions/ http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/jpa.employee/eclipselink.example.jpa.employee.extensions/]
  
 
=== Usage Instructions ===
 
=== Usage Instructions ===
Line 31: Line 31:
  
 
The following are code snippets extracted from the example to illustrate key use-cases.
 
The following are code snippets extracted from the example to illustrate key use-cases.
 +
 +
=== Domain Model ===
 +
 +
Within the domain model support for managing extensions involves a map of values in your entity type as well as a definition type.
 +
 +
[[Image:El-extension-model.gif]]
  
 
==== Values Extensions ====
 
==== Values Extensions ====
Line 37: Line 43:
  
 
<source lang="java">
 
<source lang="java">
    @Transient
+
@Transient
  
    @ValuesExtensions(table = @Table(name = "emp_ext"),  
+
@ValuesExtensions(table = @Table(name = "emp_ext"),  
            id = @Column(name = "EXT_ID"),  
+
        id = @Column(name = "EXT_ID"),  
            value = @Column(name = "EXT_VALUE"))
+
        value = @Column(name = "EXT_VALUE"))
    private Map<String, Object> extensions;
+
private Map<String, Object> extensions;
 
</source>
 
</source>
  
Line 60: Line 66:
 
</source>
 
</source>
  
''Note: The mapping must be @Transient to avoid the default mappings being applied. The confiuration section below shows how the mapping will be enabled.''
+
''Note: The mapping must be @Transient to avoid the default mappings being applied. The configuration section below shows how the mapping will be enabled.''
  
 
The underlying schema for the extension storage would look like:
 
The underlying schema for the extension storage would look like:
Line 93: Line 99:
 
</source>
 
</source>
  
=== Dynamic Types ===
+
==== Dynamic Types ====
  
 
In addition to having extensible entities this example also combines the use of EclipseLink's DynamicEntity support to allow additional types to be added to the model and for those types to be involved in relationships with static entities as well as with their extended properties.
 
In addition to having extensible entities this example also combines the use of EclipseLink's DynamicEntity support to allow additional types to be added to the model and for those types to be involved in relationships with static entities as well as with their extended properties.

Latest revision as of 16:21, 7 March 2011

Catnicon.gifUNDER CONSTRUCTIONCatnicon.gif

DISCLAIMER: This example illustrates how EclipseLink can be used with extensible entity types. The new API being developed for EclipseLink Indigo may not match this example. As the API is defined this example will be updated to reflect the final API of EclipseLink 2.3.

[edit] Extensible Entities Example

This example illustrates how EclipseLink 2.2 can be used to build a domain model that allows addition 'extension' properties, relationships, and types to added and used in the application. This approach to extensible properties includes storing the definition of the extension and limiting the entity to allowing only extension values that have been defined. This will also allow greater sharing of extension information between application instances and exposing the extended properties in the JPA 2.0 metamodel.

NOTE: This functionality is being formalized into new features for EclipseLink Indigo (2.3) in its Extensibility features.

[edit] Getting the Code

The example is being developed within the trunk of EclipseLink:

[edit] Usage Instructions

  1. Download the example project from SVN
  2. Configure project within your Eclipse development environment with necessary library dependencies
    • EclipseLink 2.2
    • JDBC Driver
    • JUnit
  3. Configure database usage with PU properties
  4. Run examples and/or test cases

[edit] Code Examples

The following are code snippets extracted from the example to illustrate key use-cases.

[edit] Domain Model

Within the domain model support for managing extensions involves a map of values in your entity type as well as a definition type.

El-extension-model.gif

[edit] Values Extensions

Values extensions use a separate table to store the extension properties. In this example the Employee entity type uses values extensions and is configured as:

@Transient
 
@ValuesExtensions(table = @Table(name = "emp_ext"), 
        id = @Column(name = "EXT_ID"), 
        value = @Column(name = "EXT_VALUE"))
private Map<String, Object> extensions;

It is annotated as @Transient so that the default JPA mappings are not applied. The configuration section below shows how the mapping is actually enabled.

El-values-extensions-schema.gif

[edit] Flex Extensions

In this example the Address class uses flex extensions and is configured as:

@Transient
 
@FlexExtensions(initial=2, create=false)
private Map<String, Object> extensions = new HashMap<String, Object>();

Note: The mapping must be @Transient to avoid the default mappings being applied. The configuration section below shows how the mapping will be enabled.

The underlying schema for the extension storage would look like:

El-flex-extensions-schema.gif

Add Values Extensions

ExtensionManager empExtMgr = new ExtensionManagerHelper(em).getExtensionManager(Employee.class);
 
empExtMgr.addExtension("middleName", String.class);
empExtMgr.addExtension("age", int.class);
empExtMgr.addExtension("alias", String.class);

[edit] Configuration

In order to enable the extensions a session customizer is used. This will use the ExtensionManagerHelper to enable extensions usage in the specified classes.

src/model.extensions.ExtensionsCustomizer

public class ExtensionsCustomizer implements SessionCustomizer {
 
    public void customize(Session session) throws Exception {
        ExtensionManagerHelper helper = new ExtensionManagerHelper(session);
 
        helper.initializeValueExtensions(Employee.class, "extensions"); 
        helper.initializeFlexExtensions(Address.class, "extensions"); 
    }
}

[edit] Dynamic Types

In addition to having extensible entities this example also combines the use of EclipseLink's DynamicEntity support to allow additional types to be added to the model and for those types to be involved in relationships with static entities as well as with their extended properties.

Create Phone Type

ExtensionManagerHelper helper = new ExtensionManagerHelper(em);
 
DynamicTypeBuilder typeBuilder = helper.getDynamicTypeBuilder("model.Phone", "phone_x");
typeBuilder.setPrimaryKeyFields("P_ID");
typeBuilder.configureSequencing("PHONE_SEQ", "P_ID");
typeBuilder.addDirectMapping("id", Integer.class, "P_ID");
typeBuilder.addDirectMapping("number", String.class, "P_NUMBER");
 
ClassDescriptor empDesc = em.unwrap(ServerSession.class).getClassDescriptorForAlias("Employee");
DynamicType fakeEmpType = new DynamicTypeImpl(empDesc, null);
typeBuilder.addOneToOneMapping("employee", fakeEmpType, "EMP_ID");
 
helper.addType(typeBuilder.getType());