Class CompoundExpression

    • Constructor Detail

      • CompoundExpression

        public CompoundExpression()
    • Method Detail

      • equals

        public boolean equals​(Object object)
        INTERNAL: Return if the expression is equal to the other. This is used to allow dynamic expression's SQL to be cached.
        Overrides:
        equals in class Expression
      • computeHashCode

        public int computeHashCode()
        INTERNAL: Compute a consistent hash-code for the expression. This is used to allow dynamic expression's SQL to be cached.
        Overrides:
        computeHashCode in class Expression
      • asOf

        public Expression asOf​(AsOfClause clause)
        Description copied from class: Expression
        Sets all tables represented by this expression to be queried as of a past time.

        Example:

          EclipseLink: employee.asOf(new AsOfClause(pastTime))
          Java: None
          SQL (Flashback): SELECT ... FROM EMPLOYEE AS OF TIMESTAMP (pastTime) t0 ...
          SQL (Generic): .. WHERE (t1.START <= pastTime) AND ((t1.END IS NULL) OR t1.END > pastTime)
         

        Set an as of clause at the expression level to still query for current objects while expressing selection criteria like:

        • query objects as of one time that met some condition at another time.
        • query objects that changed a certain way over a certain interval (querying for change).

        Simultaneously querying on two versions of the same object (one past one present) lets you express these advanced selection criteria.

        Example: Querying on past attributes using parallel expressions.

           // Finds all employees who lived in Ottawa as of a past time.
           ExpressionBuilder employee = new ExpressionBuilder();
           ExpressionBuilder pastEmployee = new ExpressionBuilder(Employee.class);
           pastEmployee.asOf(pastTime);
           Expression pastAddress = pastEmployee.get("address"); // by default address will also be as of past time.
           Expression selectionCriteria = pastAddress.get("city").equal("Ottawa").and(
               employee.equal(pastEmployee));
         

        The advantage of the parallel expression is that you can still read current objects, the as of clause will affect only the where clause / selection criteria.

        You may be tempted to rewrite the above as employee.get("address").asOf(pastTime). That is allowed but see below for the finer points involved in this.

        Example: Querying on object changes using parallel expressions.

           // Finds all employees who recently received a raise.  Note that current
           // objects are returned, so can be cached normally.
           ExpressionBuilder employee = new ExpressionBuilder();
           Expression pastEmployee = new ExpressionBuilder(Employee.class);
           pastEmployee.asOf(yesterday);
           Expression parallelJoin = employee.equal(pastEmployee);
           Expression selectionCriteria = parallelJoin.and(
               employee.get("salary").greaterThan(pastEmployee.get("salary")));
         

        Example: Querying on object changes using custom query keys

           // First define the custom query key and add it to your descriptor.
           ExpressionBuilder builder = new ExpressionBuilder(Employee.class);
           Expression joinCriteria = builder.getField("EMPLOYEE.EMP_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID"));
           OneToOneQueryKey selfReferential = new OneToOneQueryKey();
           selfReferential.setName("this");
           selfReferential.setJoinCriteria(joinCriteria);
           selfReferential.setReferenceClass(Employee.class);
           getSession().getDescriptor(Employee.class).addQueryKey(selfReferential);
        
           // Now build query as before.
           Expression employee = new ExpessionBuilder();
           Expression pastEmployee = employee.get("this").asOf(yesterday);
           Expression selectionCriteria = employee.get("salary").greaterThan(pastEmployee.get("salary"));
         

        Note in general that any parallel expression can be rewritten using a custom query key. EclipseLink will even automatically interpret x.get("this") for you so you do not need to define the above query key first.

        Full Reference:

        If an object is mapped to multiple tables, then each table will be as of the same time. Two objects mapped to the same table can not have different as of times. Conversely only expressions which have associated tables can have an as of clause.

        If an as of clause is not explicitly set an expression will use the clause of its base expression, and so on recursively until one is found or an ExpressionBuilder is reached. Some usage scenarios follow:

        • employee.asOf(pastTime).anyOf("projects"): projects as of past time.
        • expressionBuilder.asOf(pastTime): entire expression as of past time.
        • employee.asOf(pastTime).anyOf("projects").asOf(null): projects as of current time.
        • employee.anyOf("projects").asOf(pastTime): projects only as of past time.

        Watch out for x.asOf(oneTime).get("y").asOf(anotherTime).

        • emp.anyOf("phoneNumbers").asOf(yesterday) = emp.asOf(yesterday).anyOf("phoneNumbers") but:
        • emp.get("address").asOf(yesterday) != emp.asOf(yesterday).get("address").
        Whether the join is also as of yesterday depends on which table the foreign key field resides on. In an anyOf the foreign key is always on the right, but in a get (1-1) it could be on either side. For this reason employee.get("address").asOf(yesterday) is undefined as it can mean either 'my address as of yesterday', or 'my address, as of yesterday.'
        Overrides:
        asOf in class Expression
        Parameters:
        clause - A read only data object used to represent a past time.
        Returns:
        this
        See Also:
        AsOfClause, Expression.hasAsOfClause(), Session.acquireHistoricalSession(org.eclipse.persistence.history.AsOfClause), ObjectLevelReadQuery.setAsOfClause(org.eclipse.persistence.history.AsOfClause)
      • getBuilder

        public ExpressionBuilder getBuilder()
        Return the expression builder which is the ultimate base of this expression, or null if there isn't one (shouldn't happen if we start from a root)
        Specified by:
        getBuilder in class Expression
      • getFirstChild

        public Expression getFirstChild()
      • getSecondChild

        public Expression getSecondChild()
      • initializePlatformOperator

        public void initializePlatformOperator​(DatabasePlatform platform)
        INTERNAL:
      • validateNode

        public void validateNode()
        Do any required validation for this node. Throw an exception if it's incorrect. Ensure that both sides are not data expressions.
        Overrides:
        validateNode in class Expression
      • postCopyIn

        protected void postCopyIn​(Map alreadyDone)
        INTERNAL: Used for cloning.
        Overrides:
        postCopyIn in class Expression
      • resetPlaceHolderBuilder

        public void resetPlaceHolderBuilder​(ExpressionBuilder queryBuilder)
        INTERNAL: Search the tree for any expressions (like SubSelectExpressions) that have been built using a builder that is not attached to the query. This happens in case of an Exists call using a new ExpressionBuilder(). This builder needs to be replaced with one from the query.
        Specified by:
        resetPlaceHolderBuilder in class Expression
      • setFirstChild

        protected void setFirstChild​(Expression firstChild)
      • setSecondChild

        protected void setSecondChild​(Expression secondChild)