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

EclipseLink/Development/Dynamic

< EclipseLink‎ | Development
Revision as of 06:48, 13 November 2008 by Douglas.clarke.oracle.com (Talk | contribs) (Design)

Development of Dynamic Persistence in EclipseLink JPA

This page captures the functional requirements and design of a generic dynamic persistence solution that will allow consumers to specify their mappings using only using XML. The purpose of dynamic persistence is to enable simplified data access where only mapping information is required and no concrete Java model is required.

Functional Requirements

  1. Ability to use dynamic persistence through standard JPA metadata and interfaces as well as leveraging advanced EclipseLink JPA features
    1. Specify mapping metadata using persistence.xml and eclipselink-orm.xml.
  1. Common abstract base class enabling
  1. Ability to use dynamic persistence through MOXy mappings
  1. Ability to use dynamic persistence within DBWS to share common infrastructure
  1. Ability to use dynamic persistence within SDO to share common infrastructure

Future Features (Current Limitations)

In order to control the scope of this feature the following limitations have been intended and are listed here as potential future enhancements.

  1. Flexible Base Class: This feature assumes the dynamic entity base class. In the future users may want the flexibility to specify a class of their own.
  2. LimitedMapping Capability: This feature does not provide support for all mapping types. The mappings currently not supported include:
    • Inheritance
    • Embedded/EmbeddedId
    • Composite primary keys
  3. Hybrid Classes: This feature only supports DynamicEntity persistent classes. In the future developers may want the ability to combine static java classes with one or more attributes accessed dynamically. The DynamicEntityImpl class provides support for lazy loading, fetch-groups, and attribute change-tracking. Combining this with traditional static attributes and weaving complex.
  4. Native ORM: This feature relies on the JPA metadata processing of eclipselink-orm.xml. When this XML is supported through the native API then dynamic persistence should function as well

Design

The design of this feature involves several enhancements to the foundation (Core) component as well as JPA. The high level design involves:

  • XML Configuration: Extension of the eclipselink_orm_1_1.xsd
    • Add support for DYNAMIC access type in addition to FIELD and PROPERTY. Note: DYNAMIC can only be specified within this XML
    • Add support for @attribute-type on all mapping types
  • Dynamic Model
    • Public interfaces: org.eclipse.persistence.dynamic
    • Internal implementation: org.eclipse.persistence.internal.dynamic
  • Metadata Processing Enhancements
    • Handling additional access type
    • Using attribute-type instead of reflective type checking on classes
    • Error handling for configuration limitations

XML Configuration

The change to the eclipselink_orm_1_1.xsd enable

<?xml version="1.0" encoding="windows-1252" ?>
<entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
	<persistence-unit-metadata>
		<persistence-unit-defaults>
			<access>PROPERTY</access>
		</persistence-unit-defaults>
	</persistence-unit-metadata>
	<object-type-converter name="gender-converter"
		object-type="model.Gender" data-type="java.lang.String">
		<conversion-value object-value="Male" data-value="M" />
		<conversion-value object-value="Female" data-value="F" />
	</object-type-converter>
	<entity class="model.LargeProject"> 
		<table name="LPROJECT" />
		<discriminator-value>L</discriminator-value>
		<attributes>
			<basic name="budget" />
			<basic name="milestone">
				<temporal>TIMESTAMP</temporal>
			</basic>
		</attributes>
	</entity>
	<entity class="model.Address">
		<attributes>
			<id name="id">
				<column name="ADDRESS_ID" />
				<generated-value strategy="SEQUENCE" />
			</id>
			<basic name="city" />
			<basic name="country" />
			<basic name="province" />
			<basic name="postalCode">
				<column name="P_CODE" />
			</basic>
			<basic name="street" />
		</attributes>
	</entity>
	<entity class="model.PhoneNumber">
		<table name="PHONE" />
		<attributes>
			<id name="id">
				<column name="EMP_ID" updatable="false" insertable="false" />
			</id>
			<id name="type">
				<column updatable="false" />
			</id>
			<basic name="areaCode">
				<column name="AREA_CODE" />
			</basic>
			<basic name="number">
				<column name="P_NUMBER" />
			</basic>
			<many-to-one name="owner">
				<join-column name="EMP_ID" />
			</many-to-one>
		</attributes>
	</entity>
	<entity class="model.Employee">
		<secondary-table name="SALARY" />
		<attributes>
			<id name="id">
				<column name="EMP_ID" />
				<generated-value strategy="SEQUENCE" />
			</id>
			<basic name="firstName">
				<column name="F_NAME" />
			</basic>
			<basic name="lastName">
				<column name="L_NAME" />
			</basic>
			<basic name="startTime" fetch="LAZY">
				<column name="START_TIME" />
			</basic>
			<basic name="endTime" fetch="LAZY">
				<column name="END_TIME" />
			</basic>
			<basic name="gender">
				<column name="GENDER" />
				<convert>gender-converter</convert>
			</basic>
			<basic name="salary">
				<column table="SALARY" />
			</basic>
			<basic-collection name="responsibilities">
				<value-column name="RESPON_DESC" />
				<collection-table name="RESPONS" />
			</basic-collection>
			<version name="version" />
			<many-to-one name="manager" fetch="LAZY">
				<join-column name="MANAGER_ID" />
			</many-to-one>
			<one-to-many name="managedEmployees" mapped-by="manager" />
			<one-to-many name="phoneNumbers" mapped-by="owner">
				<cascade>
					<cascade-all />
				</cascade>
				<private-owned />
			</one-to-many>
			<one-to-one name="address" fetch="LAZY">
				<join-column name="ADDR_ID" />
				<cascade>
					<cascade-all />
				</cascade>
				<private-owned />
			</one-to-one>
			<many-to-many name="projects">
				<join-table name="PROJ_EMP">
					<join-column name="EMP_ID" />
					<inverse-join-column name="PROJ_ID" />
				</join-table>
			</many-to-many>
			<embedded name="period">
				<attribute-override name="startDate">
					<column name="START_DATE" />
				</attribute-override>
				<attribute-override name="endDate">
					<column name="END_DATE" />
				</attribute-override>
			</embedded>
		</attributes>
	</entity>
	<entity class="model.SmallProject">
		<table name="PROJECT" />
		<discriminator-value>S</discriminator-value>
	</entity>
	<entity class="model.Project">
		<inheritance strategy="JOINED" />
		<discriminator-column name="PROJ_TYPE" />
		<attributes>
			<id name="id">
				<column name="PROJ_ID" />
				<generated-value strategy="SEQUENCE" />
			</id>
			<basic name="description">
				<column name="DESCRIP" />
			</basic>
			<basic name="name">
				<column name="PROJ_NAME" />
			</basic>
			<version name="version" />
			<many-to-one name="teamLeader" fetch="LAZY">
				<join-column name="LEADER_ID" />
			</many-to-one>
		</attributes>
	</entity>
	<embeddable class="model.EmploymentPeriod">
		<attributes>
			<basic name="startDate">
				<temporal>DATE</temporal>
			</basic>
			<basic name="endDate">
				<temporal>DATE</temporal>
			</basic>
		</attributes>
	</embeddable>
</entity-mappings>

Dynamic Model

The dynamic model is the bulk of this feature. It provides dynamic classes to the application based on a common abstract base entity class which contains all of the EclipseLink specific support. In addition to the entity class itself there is also a simple Type-Property meta-model so that consuming applications can use the entities based on the mapping metadata.

Public Interfaces

The package org.eclipse.persistence.dynamic will provide a set of interfaces that consumers can use when interacting with dynamic entities.

  • DynamicEntity:
  • EntityType:
  • EntityProperty:
    • EntityReferenceProperty:
    • EntityCollectionProperty:
  • DynamicHelper:
  • DynamicEntityException:

Internal Implementation

The package org.eclipse.persistence.internal.dynamic includes the concrete implementation of the base entity class as well as the meta-model bridge and the byte-code weaving support for creating the concrete dynamic entity classes on the fly.

  • DynamicEntityImpl:
  • EntityTypeImpl:
  • EntityPropertyImpl:
    • EntityReferencePropertyImpl:
    • EntityCollectionPropertyImpl:
  • DynamicClassLoader:
  • DynamicAttributeAccessor:

Metadata Processing

Back to the top