Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be 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 09:33, 30 September 2010 by Guy.pelletier.oracle.com (Talk | contribs) (DescriptorQueryManager)

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 users to leverage the existing additional join expression from a descriptor query manager and allow parameters to be passed to it.

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

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

A point form list of requirements are then as follows:

  • Provide a mechanism for users to achieve the following operations
    • Multi-tenancy
    • Soft deletes
  • 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 for xml mapping file merging and overridding using the eclipselink-orm.xml
  • Allow for JPQL fragments to specify the details of the additional criteria.
  • Allow for a mechanism to pass parameters to the additional criteria.
  • Easy to use and forward compatible.
  • Respect the general JPA look and feel.

Metadata

The following sections will detail the metadata changes and modifications that are required. The additional criteria will be available in the form of annotations and xml and will be used to form the descritor query manager's additionalJoinExpression that is applied to all queries.

@AdditionalCriteria

/**
 * 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. 
 *
 * @author Guy Pelletier
 * @since EclipseLink 2.2
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface AdditionalCriteria {
    /**
     * (Required) The JPQL fragment to use as the additional criteria.
     */
    String value();
}

<additional-criteria>

An additional criteria complex element will be created to allow future expansion.

<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. 
      *
      * @author Guy Pelletier
      * @since EclipseLink 2.2
      */
     @Target({TYPE})
     @Retention(RUNTIME)
     public @interface AdditionalCriteria {
         /**
          * (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:complexType>

The additional-criteria element will be added to entity and mapped-superclass complex elements as follows

<xsd:complexType name="entity">
    <xsd:annotation>
      <xsd:documentation>
       ...
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      ...
      <xsd:element name="additional-criteria" type="orm:additional-criteria" minOccurs="0"/>
      ...
    </xsd:sequence>
    ...
</xsd:complexType>

<xsd:complexType name="mapped-superclass">
    <xsd:annotation>
      <xsd:documentation>
       ...
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      ...
      <xsd:element name="additional-criteria" type="orm:additional-criteria" minOccurs="0"/>
      ...
    </xsd:sequence>
    ...
</xsd:complexType>

Example

@AdditionalCriteria("address.city IS NOT NULL")

<additional-criteria>
  <criteria>address.city IS NOT NULL</criteria>
</additional-criteria>

Metadata overriding and merging

The additional criteria can be overridden from the eclipselink-orm.xml. XML file merging will be available as well in its current form, simply expanded to include the additional criteria. The following will be the order of precedence used to determine the which additional-criteria get applied to the descriptor.

  1. eclipselink-orm.xml
  2. mapping file
  3. on the entity class
  4. on a mapped superclass (first one to define one)

Internal mapping

The additional criteria will be used to form the additionalJoinExpression from the descriptor's query manager. The core sections below will discuss the internal handling of this additional criteria metadata.

Core

The following sections will detail the core changes and modifications that are required.

DescriptorQueryManager

The additional criteria will be used to form the existing additional join expression stored on the descriptor query manager. Additional criteria should not be used in conjunction with setting the additional join expression directly through a customizer. Doing so will have unpredictable results.

The metadata will set the additional criteria through the following new API.

public void addAdditionalCriteria(String jpqlFragment)

The jpql fragment set will be parsed into the additional join expression at initialize time. Any parsing exceptions will be thrown at that time.

JPQL fragment parsing

We will 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
Select this from <class> this where
and harness the selection criteria from that resulting query and set it to be the additional join expression. Items that will not be supported in the JPQL fragment are:
  • multiple selects
  • order by
  • group by
  • ... more to come ...

Application

New properties will be added to control the enabling/disabling of properties and to provide the parameter values. These properties can be set at both the EntityManagerFactory and EntityManager level. At the EntityManager level, however, the user must be using an isolated session.

Modifying the additional criteria properties at the EntityManager level through the following API will not be allowed and an exception will be thrown. AdditionalCriteria properties should only be supported at create entity manager time.

  1. setProperties
  2. setProperty
  3. find
  4. refresh
  5. remove

IsolatedSession API

To leverage the enable/disable users will need to use an isolated session. This session will be responsible for controlling the additional criteria to be applied to queries.

public void setAdditionalCriteriaParameterValue(String name, Object value)


Passing parameters to the additional criteria

The additional criteria parameters will also be set using EntityManagerFactory properties:

The following properties will be added to org.eclipse.persistence.config.PersistenceUnitProperties

  • eclipselink-additional-criteria-parameter

This property accept the entity name and parameter appended to the property name. The entity name and parameter should be separated by a semi-colon.

Note: Specifying a parameter to a disabled additional criteria will have no effect until the additional criteria containing the parameter is enabled.

Example:

eclipselink.additional-criteria-parameter.model.Employee:COMPANY = ORACLE

Example

With the given additional additional criterias

package model;

@AdditionalCriterias({
  @AdditionalCriteria(
    name="Company",
    enabled=true,
    value="company=:COMPANY"),
  @AdditionalCriteria(
    name="MaleEmps",
    enabled=true,
    value="gender = 'M'"),
  @AdditionalCriteria(
    name="FemaleEmps",
    enabled=false,
    value="gender = 'F'")
)
public class Employee {
  ...
}

Setting the following property on the EntityManager would return all male employees at Oracle.

eclipselink.additional-criteria-parameter.model.Employee:COMPANY = ORACLE

Passing the following properties would return all female employees at Oracle.

eclipselink.enable-additional-criteria.Employee = FemaleEmps
eclipselink.disable-additional-criteria.Employee = MaleEmps
eclipselink.additional-criteria-parameter.Employee:COMPANY = ORACLE

Bulk Parameter passing

There is currently no bulk parameter passing to all additional criteria across all descriptors. They must all be set for each descriptor separately.

Back to the top