Java Persistence API (JPA) Extensions Reference for EclipseLink, Release 2.4
  Go To Table Of Contents
 Search
 PDFComments
Comments


@ClassExtractor

Use @ClassExtractor to define a custom class indicator in place of providing a discriminator column.


Annotation Elements

Table 2-10 describes this annotation's elements.

Table 2-10 @ClassExtractor Annotation Elements

Annotation Element Description Default

java.lang.Class

(Required) The name of the class extractor to apply to the entity's descriptor




Usage

If you are mapping to an existing database, and the tables do not have a discriminator column you can still define inheritance using the @ClassExtractor annotation or <class-extractor> element. The class extractor takes a class that implements the ClassExtractor interface. An instance of this class is used to determine the class type to use for a database row. The class extractor must define a extractClassFromRow method that takes the database Record and Session.

If a class extractor is used with SINGLE_TABLE inheritance, the rows of the class type must be able to be filtered in queries. This can be accomplished by setting an onlyInstancesExpression or withAllSubclassesExpression for branch classes. These can be set to Expression objects using a DescriptorCustomizer.


Examples

Example 2-23 shows an example of using ClassExtractor to define inheritance.

Example 2-23 Using @ClassExtractor Annotation

@Entity
@Table(name="MILES_ACCOUNT")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@ClassExtractor(AirMilesClassExtractor.class)
@Customizer(AirMilesCustomizer.class)
public class AirMilesAccount implements Serializable {
    @Id
    private Long id;
    @Basic
    private String totalMiles;
    @Basic
    private String milesBalance;
    ...
}
 
@Entity
@Customizer(PreferredCustomizer.class)
public class PreferredAccount extends AirMilesAccount {
    ...
}
 
public class AirMilesClassExtractor implements ClassExtractor {
    public void extractClassFromRow(Record row, Session session) {
        if (row.get("TOTALMILES").lessThan(100000)) {
            return AirMilesAccount.class;
        } else {
            return PreferredAccount.class;
        }
    }
}
 
public class AirMilesCustomizer implements DescriptorCustomizer {
    public void customize(ClassDescriptor descriptor) {
        ExpressionBuilder account = new ExpressionBuilder();
        Expression expression = account.getField("TOTALMILES").lessThan(100000);
        descriptor.getInheritancePolicy().setOnlyInstancesExpression(expression);
    }
}
 
public class PreferredCustomizer implements DescriptorCustomizer {
    public void customize(ClassDescriptor descriptor) {
        ExpressionBuilder account = new ExpressionBuilder();
        Expression expression = account.getField("TOTALMILES").greaterThanEqual(100000);
        descriptor.getInheritancePolicy().setOnlyInstancesExpression(expression);
    }
}

Example 2-24 shows how to use the <class-extractor> element in the eclipselink-orm.xml file.

Example 2-24 Using <class-extractor> XML

<entity class="AirMilesAccount">
    <table name="MILES_ACCOUNT"/>
    <inheritance strategy="SINGLE_TABLE"/>
    <class-extractor class="AirMilesClassExtractor"/>
...
</entity>
 
<entity class="PreferredAccount">
    <customizer class="PreferredCustomizer"/>
...
</entity>


See Also

For more information, see: