This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 211323 - Add class extractor support to the EclipseLink-ORM.XML Schema
Summary: Add class extractor 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
: P2 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Guy Pelletier CLA
QA Contact:
URL:
Whiteboard: eclipselink-orm.xml
Keywords:
Depends on:
Blocks: 297531 227219
  Show dependency tree
 
Reported: 2007-11-28 14:48 EST by Guy Pelletier CLA
Modified: 2022-06-09 10:07 EDT (History)
3 users (show)

See Also:


Attachments
Proposed changes (109.36 KB, patch)
2009-12-18 14:27 EST, 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:48:10 EST
 
Comment 1 Tom Ware CLA 2009-04-16 10:59:06 EDT
Updating priority due to revised bug categorization process.  See the following page for details:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines#Priority_and_Target_Milestone 

If you feel the updated priority is incorrect, please send an email to eclipselink-users@eclipse.org.
Comment 2 Guy Pelletier CLA 2009-12-09 08:39:58 EST
Proposal for this feature.


================================ANNOTATION=====================================

/**
 * A discriminator method allows for a user defined class indicator in place of 
 * providing a discriminator column. The method has the following restrictions:
 *  - The method must be a static method on the class which has that
 *    descriptor. 
 *  - The method must take Record as an argument (e.g., a DatabaseRecord), and 
 *    must return the class to use for that record. 
 * 
 * This method will be used to decide which class to instantiate when reading 
 * from the database. It is the application's responsibility to populate any 
 * typing information in the database required to determine the class from the 
 * record.
 * 
 * The DiscriminatorMethod must only be set on the root of an entity class or
 * subhierarchy in which a different inheritance strategy is applied. The 
 * discriminator method can only be used with the SINGLE_TABLE and JOINED 
 * inheritance strategies.
 * 
 * If a DiscriminatorMethod is used then a DiscriminatorColumn cannot be used. 
 * A DiscriminatorValue also cannot be used on either the root of its 
 * subclasses.
 * 
 * In addition, for more complex configurations using a discriminator method,
 * the descriptor's withAllSubclasses and onlyInstances expressions should be 
 * set through the use of a descriptor customizer.
 *
 * @see org.eclipse.persistence.annotations.Customizer
 * @see org.eclipse.persistence.descriptors.InheritancePolicy.setWithAllSubclassesExpression(Expression)
 * @see org.eclipse.persistence.descriptors.InheritancePolicy.setOnlyInstancesExpression(Expression)
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface DiscriminatorMethod {
    /**
     * (Required) User defined discriminator method name
     */
    String name();
}

===================================XML=========================================

<xsd:complexType name="entity">
  ....

  <xsd:sequence>
    ....

    <xsd:choice>
      <xsd:sequence>
        <xsd:element name="discriminator-value" type="orm:discriminator-value" minOccurs="0"/>
        <xsd:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
      </xsd:sequence>
      <xsd:element name="discriminator-method" type="orm:discriminator-method" minOccurs="0"/>
    </xsd:choice>

    ....
  
  </xsd:sequence>

  ....
</xsd:complexType>

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

      @Target({TYPE}) @Retention(RUNTIME)
      public @interface DiscriminatorMethod {
	/**
	 * (Required) User defined discriminator method name
	 */
        String name();
      }

    </xsd:documentation>
  </xsd:annotation>
  <xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>

=================================PROCESSING====================================

InheritancePolicy.setClassExtractionMethodName(String classExtractionMethodName)

==================================EXAMPLES=====================================

@Entity
@Inheritance(strategy=JOINED)
@DiscriminatorMethod("getClassForRow")
public class Vehicle {
    ...
    
    public static Class getClassForRow(Record databaseRow) {
        return Car.class;
    }

    ...
}

<entity name="Vehicle" class="Vechicle">
  <inheritance strategy="JOINED"/>
  <discriminator-method name="getClassForRow"/>

  ...

</entity>

=================================EXCEPTIONS====================================

Throw an exception in the following cases:
 - When both a @DiscriminatorColumn and @DiscriminatorMethod are specified
 - When a discriminator value is specified (either on the root or subclass of
   a hierarchy using a discriminator method (Warning instead?)

===================================ISSUES======================================

- when using annotations should we allow users to decorate the actual method 
  with the DiscriminatorMethod annotation instead of specifying it at the 
  TYPE level?
Comment 3 Doug Clarke CLA 2009-12-09 14:05:36 EST
I believe it is better that we do not offer annotation or eclipselink-orm.xml support for the class extractor method. I would prefer to see us only address customers implementing the ClassExtractor interface.
Comment 4 Guy Pelletier CLA 2009-12-10 08:18:58 EST
Updated proposal:

We will not provide for a discriminator method, rather a discriminator 
class only.

DiscriminatorClass is already defined and used within VariableOneToOneMapping. 
We could expand this annotation to have a target of TYPE, however 
DiscriminatorClass has a required string 'discriminator' member which doesn't 
apply and re-using this annotation eliminates the option of using the single 
'value' member default  i.e. DiscriminatorClass(myClass.class).

Some suggestions:
- ClassDiscriminator
- Discriminator
- DiscriminatorClassExtractor
- ClassExtractor
- DiscriminatorExtractor
- InheritanceDiscriminator

Also, for the onlyInstances or withAllSubclass expression, if needed, users 
will have to specify them through the use of a customizer. James' suggestions
however, should be captured in a bug and addressed at a future date.

Why don't we make these expressions available from the ClassExtractor? It 
would seem like a good place for the user to define them no? Currently at
initialize time of these expressions if the inheritance policy has a class extractor, it just returns from the method. 

================================ANNOTATION=====================================

/**
 * A Discriminator allows for a user defined class indicator in place of 
 * providing a discriminator column. The class has the following restrictions:

 *  - It must extend the ClassExtractor class and implement the 
 *    extractClass(Map) method. 
 *  - That method must take a database row (a Record/Map) as an argument and 
 *    must return the class to use for that row. 
 * 
 * This method will be used to decide which class to instantiate when reading 
 * from the database. It is the application's responsibility to populate any 
 * typing information in the database required to determine the class from the 
 * row.
 * 
 * The Discriminator must only be set on the root of an entity class or
 * subhierarchy in which a different inheritance strategy is applied. The 
 * Discriminator can only be used with the SINGLE_TABLE and JOINED inheritance 
 * strategies.
 * 
 * If a Discriminator is used then a DiscriminatorColumn cannot be used. A 
 * Discriminator also cannot be used on either the root or its subclasses.
 * 
 * In addition, for more complex configurations using a Discriminator and a 
 * SINGLE_TABLE strategy, the descriptor's withAllSubclasses and onlyInstances 
 * expressions  should be set through the use of a descriptor customizer.
 *
 * @see org.eclipse.persistence.annotations.Customizer
 * @see org.eclipse.persistence.descriptors.InheritancePolicy.setWithAllSubclassesExpression(Expression)
 * @see org.eclipse.persistence.descriptors.InheritancePolicy.setOnlyInstancesExpression(Expression)
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface Discriminator {
    /**
     * (Required) User defined discriminator class
     */
    String value();
}

===================================XML=========================================

<xsd:complexType name="entity">
  ....

  <xsd:sequence>
    ....

    <xsd:choice>
      <xsd:sequence>
        <xsd:element name="discriminator-value" type="orm:discriminator-value" minOccurs="0"/>
        <xsd:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
      </xsd:sequence>
      <xsd:element name="discriminator" type="orm:discriminator" minOccurs="0"/>
    </xsd:choice>

    ....
  
  </xsd:sequence>

  ....
</xsd:complexType>

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

      @Target({TYPE}) @Retention(RUNTIME)
      public @interface Discriminator {
	/**
	 * (Required) User defined discriminator class
	 */
        String value();
      }

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

=================================PROCESSING====================================

InheritancePolicy.setClassExtractor(ClassExtractor classExtractor)

==================================EXAMPLES=====================================

@Entity
@Inheritance(strategy=JOINED)
@Discriminator(my.extractorClass.class)
public class Vehicle {
    ...
}

<entity name="Vehicle" class="Vechicle">
  <inheritance strategy="JOINED"/>
  <discriminator class="my.extractorClass.class"/>

  ...

</entity>

=================================EXCEPTIONS====================================

Throw an exception in the following cases:
 - When both a @DiscriminatorColumn and @Discriminator are specified
 - When a discriminator value is specified (either on the root or subclass of
   a hierarchy using a discriminator (Warning instead?)
Comment 5 Guy Pelletier CLA 2009-12-18 14:27:13 EST
Created attachment 154810 [details]
Proposed changes
Comment 6 Guy Pelletier CLA 2009-12-22 09:47:03 EST
Changes have been submitted.

Reviewed by: Tom Ware
 
New test (testAppleComputers) added to EntityMappingsInheritanceJUnitTestCase and MixedInheritanceJUnitTestSuite
Comment 7 Eclipse Webmaster CLA 2022-06-09 10:05:12 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink
Comment 8 Eclipse Webmaster CLA 2022-06-09 10:07:16 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink