Community
Participate
Working Groups
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.
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?
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.
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?)
Created attachment 154810 [details] Proposed changes
Changes have been submitted. Reviewed by: Tom Ware New test (testAppleComputers) added to EntityMappingsInheritanceJUnitTestCase and MixedInheritanceJUnitTestSuite
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink