This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 211302 - Add variable 1-1 mapping support to the EclipseLink-ORM.XML Schema
Summary: Add variable 1-1 mapping support to the EclipseLink-ORM.XML Schema
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL: http://wiki.eclipse.org/EclipseLink/D...
Whiteboard: Fixed in 1.0M6
Keywords:
Depends on:
Blocks: 200040
  Show dependency tree
 
Reported: 2007-11-28 14:25 EST by Guy Pelletier CLA
Modified: 2022-06-09 10:22 EDT (History)
2 users (show)

See Also:


Attachments
Code changes (195.62 KB, patch)
2008-03-26 08:58 EDT, Guy Pelletier CLA
no flags Details | Diff
Updated patch (200.33 KB, patch)
2008-03-26 10:07 EDT, Guy Pelletier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Guy Pelletier CLA 2007-11-28 14:25:42 EST
 
Comment 1 Guy Pelletier CLA 2008-03-04 11:43:42 EST
============================ Annotation Definition ============================

A VariableOneToOne can be used in conjuntion with the following annotations:
- @PrivateOwned 
- @JoinColumn(s).
- @JoinFetch

@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface VariableOneToOne {
    /**
     * (Optional) The interface class that is the target of the association. If
     * not specified it will be inferred from the type of the object being 
     * referenced.
     */
    Class targetInterface() default void.class;
    
    /**
     * (Optional) The operations that must be cascaded to the target of the 
     * association.
     */
    CascadeType[] cascade() default {};
    
    /**
     * (Optional) Defines whether the value of the field or property should
     * be lazily loaded or must be eagerly fetched. The EAGER strategy is a 
     * requirement on the persistence provider runtime that the value must be 
     * eagerly fetched. The LAZY strategy is a hint to the persistence
     * provider runtime. If not specified, defaults to LAZY.
     */
    FetchType fetch() default EAGER;
    
    /**
     * (Optional) Whether the association is optional. If set to false then a 
     * non-null relationship must always exist.
     */
    boolean optional() default true;
  
    /**
     * (Optional) The discriminator column will hold the type indicators. If 
     * the DiscriminatorColumn is not specified, the name of the discriminator 
     * column defaults to "DTYPE" and the discriminator type to STRING.
     */
    DiscriminatorColumn discriminatorColumn() default @DiscriminatorColumn;
    
    /**
     * (Optional) The list of discriminator types that can be used with this
     * VariableOneToOne. If none are specified then those entities within the
     * persistence unit that implement the target interface will be added to 
     * the list of types. The discriminator type will default as follows:
     *  - If DiscriminatorColumn type is STRING: Entity.name()
     *  - If DiscriminatorColumn type is CHAR: First letter of the Entity class
     *  - If DiscriminatorColumn type is INTEGER: The next integer after the
     *    highest integer already added.
     */
    DiscriminatorClass[] discriminatorClasses() default {};
}

@Target({}) 
@Retention(RUNTIME)
public @interface DiscriminatorClass {
    /**
     * (Required) The type indicator to be stored on the database. 
     */
    String discriminator();

    /**
     * (Required) The class to the instantiated with the given type indicator.
     */
    Class value();
}

================================ XML Definition ===============================

<xsd:complexType name="variable-one-to-one">
  <xsd:annotation>
    <xsd:documentation>

      // annotation definition to be inserted

    </xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="cascade" type="orm:cascade-type" minOccurs="0"/>
    <xsd:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
    <xsd:element name="discriminator-class" type="orm:discriminator-class" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element name="join-column" type="orm:join-column" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element name="private-owned" type="orm:emptyType" minOccurs="0"/>
    <xsd:element name="join-fetch" type="orm:join-fetch-type" minOccurs="0"/>
  </xsd:sequence>
  <xsd:attribute name="name" type="xsd:string" use="required"/>
  <xsd:attribute name="target-interface" type="xsd:string"/>
  <xsd:attribute name="fetch" type="orm:fetch-type"/>
  <xsd:attribute name="optional" type="xsd:boolean"/>
</xsd:complexType>

<xsd:complexType name="discriminator-class">
  <xsd:annotation>
    <xsd:documentation>

      // annotation definition to be inserted

    </xsd:documentation>
  </xsd:annotation>
  <xsd:attribute name="discriminator" type="xsd:string" use="required"/>
  <xsd:attribute name="value" type="xsd:string" use="required"/>
</xsd:complexType>

================================== Example 1 ==================================

@VariableOneToOne(
    cascade={ALL},
    fetch=LAZY,
    discriminatorColumn=@DiscriminatorColumn(name="CONTACT_TYPE"),
    discriminatorClasses={
        @DiscriminatorClass(discriminator="E", value="Email.class"), 
        @DiscriminatorClass(discriminator="P", value="Phone.class")
    }
}
@JoinColumn(name="CONTACT_ID", referencedColumnName="C_ID")
@PrivateOwned
@JoinFetch(INNER)
public Contact getContact() {
    return contact;
}

Equivalent XML specification:

<variable-one-to-one name="contact" fetch="LAZY">
    <cascade>
        <cascade-all/>
    </cascade>
    <discriminator-column name="CONTACT_TYPE"/>
    <discriminator-class discriminator="E" value="Email.class"/>
    <discriminator-class discriminator="P" value="Phone.class"/>
    <join-column name="CONTACT_ID" referenced-column-name="C_ID"/>
    <private-owned/>
    <join-fetch>INNER</join-fetch>
</variable-one-to-one>

================================== Example 2 ==================================

@VariableOneToOne(
    discriminatorClasses={
        @DiscriminatorClass(discriminator="D", value="Documentary.class"), 
        @DiscriminatorClass(discriminator="F", value="Film.class")
    }
}
public Program getProgram() {
    return program;
}

NOTES: 
- The JoinColumn will default to @JoinColumn(name="PROGRAM_ID", referencedColumnName="ID")
- The DiscriminatorColumn will default to DTYPE

Equivalent XML specification:

<variable-one-to-one name="program">
    <discriminator-class discriminator="D" value="Documentary.class"/>
    <discriminator-class discriminator="F" value="Film.class"/>
</variable-one-to-one>

====================== Example 3 (minimal configuration) ======================
  
public Contact getContact() {
    return contact;
}

NOTES:
- When processing the entities of the PU, those found to implement the Contact 
  interface will be added to the types of the VariableOneToOneMapping. Let's 
  pretended Email and Phone exist and implement the Contact interface, then the 
  following types are added (assuming their entity names have been defaulted to 
  the class name)
    - @DiscriminatorClass(type="Email", value="Documentary.class"), 
    - @DiscriminatorClass(type="Phone", value="Film.class")
- JoinColumn will default to @JoinColumn(name="CONTACT_ID", referencedColumnName="ID")
- The DiscriminatorColumn will default to DTYPE

Equivalent XML specification:

<variable-one-to-one name="contact"/>

================================== Example 4 ==================================

@VariableOneToOne(
    column=@DiscriminatorColumn(name="PROGRAM_TYPE", discriminatorType="INTEGER"),
    discriminatorClasses={
        @DiscriminatorClass(discriminator="1", value="Classic.class"), 
        @DiscriminatorClass(discriminator="5", value="Film.class")
    }
}
public Program getProgram() {
    return program;
}

NOTES:
- In the metadata processing we come across the Comedy class and it implements the Program interface as well. The following @DiscriminatorType will be defaulted:
    - @DiscriminatorType(type="6", value="Comedy.class")

Equivalent XML specification:

<variable-one-to-one name="program">
    <discriminator-column name="PROGRAM_TYPE" discriminator-type="INTEGER"/>
    <discriminator-class discriminator="1" value="Classic.class"/>
    <discriminator-class discriminator="5" value="Film.class"/>
</variable-one-to-one>

================================= Error cases =================================

 - Multiple classes for the the same type.


================================= Other items =================================

 - Primary key join column support?
Comment 2 Guy Pelletier CLA 2008-03-04 11:49:34 EST
Clarification:

================================= Error cases =================================

 - Multiple classes for the the same 'discriminator'.

Comment 3 Doug Clarke CLA 2008-03-05 15:53:30 EST
I am confused about the usage of JoinFetch on a Variable1:1 mapping. In order to do a join you must have a specific target table and this mapping is one that does not know what the target table is without evaluating contents of the source and could result in a different target tables for each row.
Comment 4 Guy Pelletier CLA 2008-03-26 08:58:56 EDT
Created attachment 93577 [details]
Code changes

Code changes for this functionality are attached.

Couple notes:

- There is no join-fetch support with variable one to one
- JoinColumn referencedColumnName when specified must be the query key and not an actual column since it may very between classes that implement the interface.
Comment 5 Guy Pelletier CLA 2008-03-26 10:07:36 EDT
Created attachment 93587 [details]
Updated patch
Comment 6 Guy Pelletier CLA 2008-03-31 14:20:07 EDT
Changes have been submitted.

Reviewed by: Gordon Yorke

New test suite added:
org.eclipse.persistence.testing.tests.jpa.relationships.RelationshipModelJUnitTestSuite

New tests added to:
org.eclipse.persistence.testing.tests.jpa.xml.relationships.EntityMappingsRelationshipsJUnitTestCase
- testCreateExtendedItem
- testModifyExtendedItem
- testVerifyExtendedItem
Comment 7 Doug Clarke CLA 2008-04-11 08:42:08 EDT
Added examples to Functional Spec - see URL above
Comment 8 Eclipse Webmaster CLA 2022-06-09 10:22:46 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink