This site is maintained for archival purposes only. Eclipse projects have transitioned to GitHub and Eclipse GitLab. Use the Projects search tool to locate your project and access its latest code and issue tracker.
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