// Creates a Hibernate concatenation if there are multiple identifierproperties
  // note prefix includes the dot at the end
  private String createIdentifierLeftClause(List<Property> identifierProperties, String prefix) {
    final StringBuilder sb = new StringBuilder();
    for (Property prop : identifierProperties) {
      if (sb.length() > 0) {
        sb.append(" || '" + IdentifierProvider.SEPARATOR + "' || ");
      }
      // note to_char is added to handle null values correctly
      if (prop.getReferencedProperty() == null) {
        sb.append("COALESCE(to_char(" + prefix + prop.getName() + "),'')");
      } else {
        final List<Property> newIdentifierProperties =
            prop.getReferencedProperty().getEntity().getIdentifierProperties();
        sb.append(
            createIdentifierLeftClause(newIdentifierProperties, prefix + prop.getName() + "."));
      }
    }

    return "(" + sb.toString() + ")";
  }
  private void createSavePaymentTerm() {
    setAccess();
    final List<PaymentTerm> result = new ArrayList<PaymentTerm>();
    for (int i = 0; i < NO_OF_PT; i++) {
      final PaymentTerm source =
          OBDal.getInstance().get(PaymentTerm.class, "66BA1164A7394344BB9CD1A6ECEED05D");
      final PaymentTerm pt = (PaymentTerm) DalUtil.copy(source, false);
      pt.setName(PREFIX + " test " + i);
      pt.setOrganization(OBContext.getOBContext().getCurrentOrganization());

      // force new
      // now add a payment termline
      for (int j = 0; j < NO_OF_PT_LINE; j++) {
        final PaymentTermLine ptl = OBProvider.getInstance().get(PaymentTermLine.class);
        ptl.setExcludeTax(true);
        ptl.setLastDayCutoff(new Long(10));
        ptl.setMaturityDate1(new Long(5));
        ptl.setMaturityDate2(new Long(1));
        ptl.setMaturityDate3(new Long(1));
        ptl.setOffsetMonthDue(new Long(j));
        ptl.setLineNo((long) j);
        ptl.setOverduePaymentDayRule("1");
        ptl.setOverduePaymentDaysRule((long) 10);
        ptl.setNextBusinessDay(true);
        ptl.setRest(true);
        ptl.setPaymentTerms(pt);
        ptl.setPercentageDue(new BigDecimal(1));
        pt.getFinancialMgmtPaymentTermLineList().add(ptl);
      }
      result.add(pt);
    }
    for (final PaymentTerm pt : result) {
      OBDal.getInstance().save(pt);
    }
    OBDal.getInstance().commitAndClose();

    // count the children
    int cnt = 0;
    for (PaymentTerm pt : result) {
      PaymentTerm insertedPaymentTerm = OBDal.getInstance().get(PaymentTerm.class, pt.getId());
      cnt++;
      for (Property p : pt.getEntity().getProperties()) {
        if (p.isChild()) {
          cnt += ((Collection<?>) insertedPaymentTerm.get(p.getName())).size();
        }
      }
    }
    TOTAL_PT_PTL = cnt;
  }
 public String getJoinStatement() {
   return " left outer join " + ownerAlias + "." + property.getName() + " as " + joinAlias;
 }
  protected String getOrderByClausePart(String orderByParam) {
    String localOrderBy = orderByParam;
    final boolean asc = !localOrderBy.startsWith("-");
    String direction = "";
    if (!asc) {
      localOrderBy = localOrderBy.substring(1);
      direction = " desc ";
    }

    final List<String> paths = new ArrayList<String>();

    // handle the following case:
    // table.window.identifier as the sort string
    boolean isIdenfitier =
        localOrderBy.equals(JsonConstants.IDENTIFIER)
            || localOrderBy.endsWith("." + JsonConstants.IDENTIFIER);
    if (isIdenfitier) {
      Entity searchEntity = getEntity();
      // a path to an entity, find the last entity
      final String prefix;
      if (!localOrderBy.equals(JsonConstants.IDENTIFIER)) {
        // be lazy get the last property, it belongs to the last entity
        final Property prop = DalUtil.getPropertyFromPath(searchEntity, localOrderBy);
        Check.isNotNull(
            prop, "Property path " + localOrderBy + " is not valid for entity " + searchEntity);
        searchEntity = prop.getEntity();
        prefix = localOrderBy.substring(0, localOrderBy.lastIndexOf(".") + 1);
      } else {
        prefix = "";
      }
      for (Property prop : searchEntity.getIdentifierProperties()) {
        if (prop.isOneToMany()) {
          // not supported ignoring it
          continue;
        }
        if (!prop.isPrimitive()) {
          // get identifier properties from target entity
          // TODO: currently only supports one level, recursive
          // calls have the danger of infinite loops in case of
          // wrong identifier definitions in the AD
          final Entity targetEntity = prop.getTargetEntity();
          for (Property targetEntityProperty : targetEntity.getIdentifierProperties()) {
            paths.add(prefix + prop.getName() + "." + targetEntityProperty.getName());
          }
        } else {
          paths.add(prefix + prop.getName());
        }
      }
    } else {
      paths.add(localOrderBy);
    }

    final StringBuilder sb = new StringBuilder();
    boolean addComma = false;
    for (String path : paths) {
      if (addComma) {
        sb.append(", ");
      }
      addComma = true;
      final String resolvedPath =
          resolveJoins(JsonUtils.getPropertiesOnPath(getEntity(), path), path);
      sb.append(resolvedPath);
      sb.append(direction);
    }
    return sb.toString();
  }