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 "EclipseLink/Development/JPA2.0/uni-directional onetomany mapping"

(Details)
(Requirements)
Line 20: Line 20:
 
#### if provided together with @JoinColumn or @JoinColumns - UnidirectionalManyToMany on the source (new)
 
#### if provided together with @JoinColumn or @JoinColumns - UnidirectionalManyToMany on the source (new)
 
##### No mapping for foreign key on the target.
 
##### No mapping for foreign key on the target.
##### Addition or removal of the target from the source should trigger target's version change.
+
##### Addition or removal of the target to/from the source should trigger source's version change.
 
#### otherwise - ManyToMany on the source (relational table could be provided in @JoinTable, otherwise generated) (already implemented in Eclipselink 1.0).
 
#### otherwise - ManyToMany on the source (relational table could be provided in @JoinTable, otherwise generated) (already implemented in Eclipselink 1.0).
 
# Core.
 
# Core.

Revision as of 11:24, 13 August 2008

Uni-directional OneToMany with Target Table

JPA 2.0 Root | Enhancement Request

Feedback

Issue Summary

The JPA 1.0 specification only allows for uni-direction OneToMany mapping that uses a Join Table but the JPA 2.0 specification will require support for a uni-direction OneToMany mapping where no Join Table is involved. The defaulting rules for a Uni-directional OneToMany have not changed and defaulted uni-directional OneToMany mappings will still default to using a Join Table but if the developer provides @JoinColumn or @JoinColumns on the uni-directional OneToMany mapping then a target table mapping must be used.

See JPA 2.0 ED 9.1.33 for details

General Solution

A new mapping UnidirectionalOneToManyMapping will be defined. It will handle adding and removal of target objects following the pattern established in ManyToManyMapping. The new mapping will not be private owned by default.

Requirements

  1. JPA.
    1. @OneToMany resolved as the following mapping in the core:
      1. if has mappedBy - OneToMany on the source; ManyToOne on the target (already implemented in Eclipselink 1.0);
      2. if doesn't have mappedBy
        1. if provided together with @JoinColumn or @JoinColumns - UnidirectionalManyToMany on the source (new)
          1. No mapping for foreign key on the target.
          2. Addition or removal of the target to/from the source should trigger source's version change.
        2. otherwise - ManyToMany on the source (relational table could be provided in @JoinTable, otherwise generated) (already implemented in Eclipselink 1.0).
  2. Core.
    1. Define a new UnidirectionalOneToManyMapping that
      1. A new version of one to many mapping that doesn't require the target foreign key to be mapped by the target descriptor.
      2. All EclipseLink featurues (unless explicitly exempted) should work with the new mapping: cascading, joins, historical sessions, batch reading, etc.

Details

The new class UnidirectionalOneToManyMapping will be derived from OneToManyMapping overriding only the methods that deal with adding and removing of the traget objects. It will follow the pattern of ManyToManyMapping. The following queries (that could be customized by user) used to managed target objects:

  1. On delition of the source object
    1. if privately owned then processing inherited from OneToManyMapping: a single deleteAllQuery does that if conditions are right (target is not mapped to multiple tables, doesn't need to cascade delete, etc.).
    2. if not privately owned then removeAllTargetsQuery is used - it sets in a single sql all target foreign keys to null: UPDATE EMPLOYEE SET MANAGER_ID = NULL WHERE (MANAGER_ID = 1)
  2. if the new target object is added to the source then addTargetQuery is used: UPDATE EMPLOYEE SET MANAGER_ID = 1 WHERE (EMP_ID = 2)
  3. if the target object is removed from the source then removeTargetQuery is used: UPDATE EMPLOYEE SET MANAGER_ID = null WHERE ((MANAGER_ID = 1) AND (EMP_ID = 2))

Implementation sequence

  1. First the new class UnidirectionalOneToMany weill be implemented in Core along with the simple tests (add / remove target objects).
    1. That should include all the features that used by JPA (joins).
    2. Because all the reading methods are inherited without change from OneToMany the advanced testing of reading could be postponed or skipped altogether.
  2. Add JPA support - annotation and orm xml processing.
    1. Add JPA tests.
  3. Add support to the remaining Eclipselink features (not currently used by JPA) batch reading, historical sessions, etc.

Additional improvements to consider

The spec. says (2.1.8) that "application that bears responsibility for maintaining the consistency of runtime relationship", however users bound to do things like deleting the target object without first removing it from the source. If there's time for that, consider:

  1. Weaving of the target adding an attribute mapped to the foreign key - that would allow efficient removal of the target from the source in the cache.
  2. Add an option allowing target descriptor to know all source (of unidirectional mappings) descriptors, may be add to the cache key of the target object the pk of the source object (on adding to source - remove the source pk on removal from the source) - that whould allow efficient removal of the target from the source in the cache.
  3. In case the target object changes its foreign key as well as updated in the same transaction currently 2 separate sql are issued - in many cases those 2 sql could be merged into one.

Work Required

  1. Develop model for testing including joining queries
    approx 1 day
  2. Develop a mapping that supports uni-directional OneToMany mapping in EclipseLink that does not use Join Table
    approx 7 days
  3. Process @JoinColumn annotation and xml on a OneToMany mapping and test
    approx 2 days

Back to the top