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.
Difference between revisions of "EclipseLink/Examples/JPA/Extensible"
(→Flex Extensions) |
|||
Line 64: | Line 64: | ||
[[Image:El-flex-extensions-schema.gif]] | [[Image:El-flex-extensions-schema.gif]] | ||
+ | |||
+ | '''Add Values Extensions''' | ||
+ | <source lang="java"> | ||
+ | ExtensionManager empExtMgr = new ExtensionManagerHelper(em).getExtensionManager(Employee.class); | ||
+ | |||
+ | empExtMgr.addExtension("middleName", String.class); | ||
+ | empExtMgr.addExtension("age", int.class); | ||
+ | empExtMgr.addExtension("alias", String.class); | ||
+ | </source> | ||
==== Configuration ==== | ==== Configuration ==== |
Revision as of 11:46, 2 March 2011
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.
NOTE: This functionality is being formalized into new features for EclipseLink Indigo (2.3) in its Extensibility features.
Getting the Code
The example is being developed within the trunk of EclipseLink:
- SVN: [1]
Usage Instructions
- Download the example project from SVN
- Configure project within your Eclipse development environment with necessary library dependencies
- EclipseLink 2.2
- JDBC Driver
- JUnit
- Configure database usage with PU properties
- Run examples and/or test cases
Code Examples
The following are code snippets extracted from the example to illustrate key use-cases.
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.
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 confiuration section below shows how the mapping will be enabled.
The underlying schema for the extension storage would look like:
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);
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"); } }
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());