Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/Development/AdditionalCriteria

< EclipseLink‎ | Development
Revision as of 11:57, 22 September 2010 by Unnamed Poltroon (Talk) (Additional Criteria Callback Method)

Additional Criteria Requirements and Design

Enhancement Request: bug 322008

This work will introduce an additional criteria EclipseLink users can apply to a descriptors default queries in turn providing them with a filtering option. This filtering option will allow for the user to enable and disable the filter as needed at runtime.

See the following blog from Doug discussing filters and their current usage though a drscriptor customizer.

http://java-persistence.blogspot.com/2010/08/eclipselink-filters-how-to.html

A point form list of requirements are then as follows:

  • Simplify the definition and usage of EclipseLink's additional join expressions using Eclipselink metadata.
    • Allow additional criteria to be specified through the use of annotations and xml.
    • Allow users the option to provide their own class to control the additional criteria for specific queries (again using annotations and xml).
  • Allow users the option to enable and disable additional criteria.
  • Respect the general JPA look and feel and XML overridding rules.
  • Allow for xml mapping file merging and overridding using the eclipselink-orm.xml
  • Allow for JPQL fragments to specify the details of the additional criteria.
  • Easy to use and forward compatible.

Metadata

The additional criteria will be available in the form of annotations and/or xml where additional criteria can be overriden from the eclipselink-orm.xml. XML file merging will be available as well (in its current form, simply expanded to include the additional criteria)

An example of the XML override is as follows:

  • mapping.xml defines an additional-criteria
  • eclipselink.xml defines an additional-criteria-group

The outcome is that the additional-criteria-group from the eclipselink-orm.xml is applied and overrides the additional-criteria from the mapping.xml.

The following new elements will be added to <entity> and <mapped-superclass> complex elements to facilitate the additional criteria support.

 <xsd:choice minOccurs="0">
   <xsd:element name="additional-criteria" type="orm:additional-criteria"/>
   <xsd:element name="additional-criteria-group" type="orm:additional-criteria-group"/>
 </xsd:choice>

Additional Criteria

The additional criteria will tie into the existing additionalJoinExpression from the descriptor's query manager. See the JPQL fragment section below that will discuss how this value will be populated.

<xsd:complexType name="additional-criteria">
  <xsd:annotation>
    <xsd:documentation>

      /**
       * Can be specified at the Entity or MappedSuperclass level. When specified at 
       * the mapped superclass level, it applies to all inheriting entities unless 
       * those entities define their own additional criteria, at which point the 
       * additional criteria from the mapped superclass is ignored. 
       * 
       * Additional criteria can be specified as a single item or within an additional 
       * criteria group. A single additional criteria or an additional criteria group 
       * can not be specified in conjunction with an additional criteria callback. 
       * 
       * @author Guy Pelletier
       * @since EclipseLink 2.2
       */
      @Target({TYPE})
      @Retention(RUNTIME)
      public @interface AdditionalCriteria {
          /**
           * (Optional) The name of the additional criteria. Naming allows the 
           * capability of turning off individual criteria based on name. 
           */
          String name() default "default";
    
          /**
           * (Optional) By default, the additional criteria is not enabled and applied.
           */
          boolean enabled() default false;
    
          /**
           * (Required) The JPQL fragment to use as the additional criteria.
           */
          String value();
      }

    </xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
      <xsd:element name="criteria" type="xsd:string"/>
  </xsd:sequence>
  <xsd:attribute name="name" type="xsd:string"/>
  <xsd:attribute name="enabled" type="xsd:boolean"/>
</xsd:complexType>

Example

  @AdditionalCriteria(
    name="CitySpecified",
    enabled=true,
    value="address.city IS NOT NULL"
  )

  <additional-criteria name="CitySpecified" enabled="true">
    <criteria>address.city IS NOT NULL</criteria>
  </additional-criteria>


Additional Criteria Callback - through existing EntityListener

The users will be able to control how the additionalJoinExpression is expressed through an EntityListener. We will allow them to decorate the entity listener with a new callback annotation (AdditionalCallbackMethod) to specify those methods that should be used to generate additional join expressions.

Using a callback class, users can further control which additional criteria is used for individual query classes. See the AdditionalCriteriaCallbackMethod below.

  <xsd:complexType name="entity-listener">
    <xsd:annotation>
      <xsd:documentation>

        Defines an entity listener to be invoked at lifecycle events
        for the entities that list this listener.

      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="description" type="xsd:string" minOccurs="0"/>
      <xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
      <xsd:element name="post-persist" type="orm:post-persist" 
                   minOccurs="0"/>
      <xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
      <xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
      <xsd:element name="pre-update" type="orm:pre-update" minOccurs="0"/>
      <xsd:element name="post-update" type="orm:post-update" minOccurs="0"/>
      <xsd:element name="post-load" type="orm:post-load" minOccurs="0"/>
      <xsd:element name="additional-criteria-method" type="orm:additional-criteria-method" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="class" type="xsd:string" use="required"/>
  </xsd:complexType>

Example

  @EntityListener(CustomerUserCriteria.class)

  <entity-listener class="CustomerUserCriteria"/>

Additional Criteria Callback Method

The additional criteria callback method(s) control which methods from the callback class are used to control the additional criteria and to which queries they apply.

<xsd:complexType name="additional-criteria-callback-method">
  <xsd:annotation>
    <xsd:documentation>
 
      /**
       * An additional criteria callback method(s) is specified on an additional
       * criteria callback class. It also defines the EclipseLink queries that should
       * call the method on execution.
       * 
       * @author Guy Pelletier
       * @since EclipseLink 2.2
       */
      @Target({METHOD})
      @Retention(RUNTIME)
      public @interface AdditionalCriteriaCallbackMethod {    
          /**
           * (Optional) The list of EclipseLink query classes that will accept the
           * additional criteria. E.g. ReadAllQuery.class, DeleteObjectQuery.class.
           * By defaul the callback method is applied to all queries.
           * 
           * There can be multiple AdditionalCriteriaCallbackMethod on a callback
           * class.
           */
          Class[] value() default {};
      }
  
    </xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
      <xsd:element name="query-class" type="xsd:string" maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>

Example

public class CustomerUserCriteria {
  @AdditionalCriteriaCallbackMethod 
  public void handleAll(DatabaseQuery query) {}

  @AdditionalCriteriaCallbackMethod({ReadAllQuery.class, ReadObject.class}) 
  public void handleRead(DatabaseQuery query) {}

  @AdditionalCriteriaCallbackMethod({DeleteObjectQuery.class, DeleteAllQuery.class}) 
  public void handleDelete(DatabaseQuery query) {}
}

<entity-listener class="CustomerUserCriteria">
  <callback-method name="handleAll"/>
  <callback-method name="handleRead">
    <query-class>ReadAllQuery</query-class>
    <query-class>ReadObjectQuery</query-class>
  </callback-method>
  <callback-method name="handleDelete">
    <query-class>org.eclipse.persistence.queries.DeleteAllQuery</query-class>
    <query-class>org.eclipse.persistence.queries.DeleteObjectQuery</query-class>
  </callback-method>
</entity-listener>

Notes

  • The org.eclipse.persistence.queries package will be appended by default.
  • An additional criteria callback class is parsed similarly as an entity listener class. That is, it is pased for more additional criteria callback methods, however XML will override any similarly named criteria callback method in annotations.

Exception cases

The following configurations will throw an exception:

  1. More than one additional criteria specified, that is:
    1. an @AdditionalCriteria with an @AdditionalCriteriaGroup
    2. an @AdditionalCriteria with an @AdditionalCriteriaMethod (on entity listener or entity class)
    3. an @AdditionalCriteriaGroup with an @AdditionalCriteriaMethod (on entity listener or entity class)
    4. an @AdditionalCriteriaMethod for overlapping queries on both the EntityListener and Entity class

Core

JPQL fragment

The current notion will be to tie into the existing JPQL parser to parse the additional criteria where the only alias allowed will be 'this'. We will prepend the select statement, e.g. "Select this from <class> this where" and harness the selection criteria from that resulting query and appended to the executing query.

For an additional criteria group, each selection criteria harnessed from each additional criteria within the group will be joined with an 'AND'

Items that will not be supported in the JPQL fragment are:

  • multiple selects
  • order by
  • group by
  • ... more to come ...

Query manager

Will be responsible for controlling the additional criteria that is applied to the queries. That is, it will take into consideration the additional criteria that is enabled (only a single criteria or group or callback can be enabled at one time). The query manager is responsible for directing the executing query to the related/associated callback method from the callback class.

Back to the top