public void getOrderLargerThan() {
    EntityManager em = createEntityManager();

    ExpressionBuilder builder1 = new ExpressionBuilder(Order.class);
    ExpressionBuilder builder2 = new ExpressionBuilder(Order.class);
    Expression o1Quantity = builder1.get("quantity");
    Expression o2Quantity = builder2.get("quantity");
    Expression quantityComparison = o1Quantity.greaterThan(o2Quantity);
    Expression o2CustomerName = builder2.get("customer").get("name");
    Expression nameComparison = o2CustomerName.equal("Jane Smith");
    Expression whereClause = quantityComparison.and(nameComparison);

    ReadAllQuery raq = new ReadAllQuery();
    raq.setSelectionCriteria(whereClause);
    raq.setReferenceClass(Order.class);
    raq.useDistinct();
    List expectedResult = (List) getServerSession().executeQuery(raq);

    String ejbqlString =
        "SELECT DISTINCT o1 FROM OrderBean o1, OrderBean o2 WHERE o1.quantity > o2.quantity AND"
            + " o2.customer.name = 'Jane Smith' ";
    List result = em.createQuery(ejbqlString).getResultList();
    // only 1 order
    Assert.assertEquals(
        "Get order larger than test failed: data validation error", result.size(), 1);
    Assert.assertTrue(
        "Get order larger than test failed", comparer.compareObjects(expectedResult, result));
  }
예제 #2
0
  protected Expression processPropertyTracedownTooneOptimized(
      Attribute<?, ?> attr, Expression builder, List<Parameter> parameters) {
    ConditionQuery subQuery = getTraceDownQuery();

    Expression finalExp = null;
    for (PropertyCondition subPc : subQuery.getConditions()) {
      if (subPc.isReturnSimpleExpression()) {
        Expression subExp = subPc.processProperty(builder.get(getProp()), parameters);
        if (finalExp == null) {
          finalExp = subExp;
        } else {
          finalExp = finalExp.and(subExp);
        }
      } else {
        // low-performance query since an extra layer of exists added
        // but this is the only way to make it work.
        // this situation is rare. So we may do not need to optimize it
        Expression subBuilder = new ExpressionBuilder();
        Expression subExp = subPc.processProperty(subBuilder, parameters);
        ReportQuery childQuery = formRelationReportQuery(attr, subBuilder);
        childQuery.retrievePrimaryKeys();
        childQuery.setSelectionCriteria(subBuilder.equal(builder.get(getProp())).and(subExp));
        if (finalExp == null) {
          finalExp = builder.exists(childQuery);
        } else {
          finalExp = finalExp.and(builder.exists(childQuery));
        }
      }
    }
    return finalExp;
  }
  /**
   * Iterate the set of variables declared in an outer scope and connect the inner variable
   * expression with the outer one.
   */
  public Expression joinVariables(Set variables) {
    if ((outer == null) || (variables == null) || variables.isEmpty()) {
      // not an inner query or no variables to join
      return null;
    }
    Expression expr = null;
    for (Iterator i = variables.iterator(); i.hasNext(); ) {
      String name = (String) i.next();
      VariableNode var = new VariableNode(name);
      Expression innerExpr = var.generateExpression(this);
      Expression outerExpr = var.generateExpression(outer);

      // Join them only if they are not the same.
      if (innerExpr != outerExpr) {
        Expression join = innerExpr.equal(outerExpr);
        expr = var.appendExpression(expr, join);
      }
    }
    return expr;
  }
예제 #4
0
  /**
   * @param type
   * @param builder
   * @param parameters
   * @return a fully parameterized query. A default value for this query should be set to query at a
   *     late time.
   */
  public Expression processProperty(Expression builder, List<Parameter> parameters) {
    Attribute<?, ?> attr = getAttribute();

    Operator op = getOperator();
    ConditionQueryParameter p;
    // convenient expression, only used by simple case
    Expression exp = builder.get(getProp());

    switch (op) {

        // Operator for primtive type first: lt, le, gt, ge, eq, ne, between,
        // notbetween, like(String), notlike(String), checked, unchecked
        // oneof(in(...)), notoneof(notin(...))
      case lt:
        return processPropertyLt(attr, builder, parameters);
      case le:
        return processPropertyLe(attr, builder, parameters);
      case eq:
        return processPropertyEq(attr, builder, parameters);
      case gt:
        return processPropertyGt(attr, builder, parameters);
      case ge:
        return processPropertyGe(attr, builder, parameters);
      case ne:
        return processPropertyNe(attr, builder, parameters);
      case between:
        return processPropertyBetween(attr, builder, parameters);
      case notbetween:
        return processPropertyNotBetween(attr, builder, parameters);
      case like:
        return processPropertyLike(attr, builder, parameters);
      case notlike:
        return processPropertyNotLike(attr, builder, parameters);
      case oneof:
        return processPropertyOneof(attr, builder, parameters);
      case notoneof:
        // for direct follection.
        return processPropertyNotOneof(attr, builder, parameters);
      case checked:
        exp = exp.equal(true);
        return exp;
      case unchecked:
        exp = exp.equal(false);
        return exp;
        /** *************** The above is for comparison of primitive value */
        // null, notnull are not primitive attr, only property with single
        // value
      case notnull:
        if (attr.isCollection()) {
          return this.processPropertyNotEmpty(attr, builder, parameters);
        } else {
          exp = exp.notNull();
          return exp;
        }
      case isnull:
        if (attr.isCollection()) {
          return this.processPropertyEmpty(attr, builder, parameters);
        } else {

          if (JpaMetamodelHelper.isRelation(attr) && !JpaMetamodelHelper.isRelationOwner(attr)) {
            ExpressionBuilder main = new ExpressionBuilder();
            ReportQuery subQuery = formRelationReportQuery(attr, main);
            subQuery.setSelectionCriteria(main.equal(builder.get(getProp())));
            subQuery.addAttribute("id");

            exp = builder.notExists(subQuery);

          } else {
            exp = exp.isNull();
          }
          return exp;
        }

        // -----------------size operation for collection: size, sizegt,
        // sizelt, empty, notempty
      case size:
        // do not work for simple collection.
        // need test case for simple collection
        p = new ConditionQueryParameter(this, getQuery().getPrefix() + parameters.size());
        parameters.add(p);
        if (JpaMetamodelHelper.isRelation(attr)) {
          exp = builder.size(getProp()).equal(builder.getParameter(p.getParamName()));
        } else {
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=396892
          exp =
              builder
                  .subQuery(this.formSizeReportQuery(attr, builder))
                  .equal(builder.getParameter(p.getParamName()));
        }
        return exp;
      case sizeGt:
        p = new ConditionQueryParameter(this, getQuery().getPrefix() + parameters.size());
        parameters.add(p);
        if (JpaMetamodelHelper.isRelation(attr)) {
          exp = builder.size(getProp()).greaterThan(builder.getParameter(p.getParamName()));
        } else {
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=396892
          exp =
              builder
                  .subQuery(this.formSizeReportQuery(attr, builder))
                  .greaterThan(builder.getParameter(p.getParamName()));
        }
        return exp;
      case sizeLt:
        p = new ConditionQueryParameter(this, getQuery().getPrefix() + parameters.size());
        parameters.add(p);
        if (JpaMetamodelHelper.isRelation(attr)) {
          exp = builder.size(getProp()).lessThan(builder.getParameter(p.getParamName()));
        } else {
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=396892
          exp =
              builder
                  .subQuery(this.formSizeReportQuery(attr, builder))
                  .lessThan(builder.getParameter(p.getParamName()));
        }
        return exp;
      case empty:
        return this.processPropertyEmpty(attr, builder, parameters);
      case notempty:
        return this.processPropertyNotEmpty(attr, builder, parameters);
      case tracedown:
        if (attr.isCollection()) {
          if (isAllColllectionMode()) {
            return this.processPropertyTracedownToManyAll(attr, builder, parameters);
          } else if (isNoneColllectionMode()) {
            return this.processPropertyTracedownToManyNone(attr, builder, parameters);
          } else {
            return this.processPropertyTracedownToManySomeOptimized(attr, builder, parameters);
          }

        } else {
          return this.processPropertyTracedownTooneOptimized(attr, builder, parameters);
        }
      default:
        break;
    }
    return null;
  }