private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) {
    String path = subcriteria.getPath();

    // some messy, complex stuff here, since createCriteria() can take an
    // aliased path, or a path rooted at the creating criteria instance
    Criteria parent = null;
    if (path.indexOf('.') > 0) {
      // if it is a compound path
      String testAlias = StringHelper.root(path);
      if (!testAlias.equals(subcriteria.getAlias())) {
        // and the qualifier is not the alias of this criteria
        //      -> check to see if we belong to some criteria other
        //          than the one that created us
        parent = aliasCriteriaMap.get(testAlias);
      }
    }
    if (parent == null) {
      // otherwise assume the parent is the the criteria that created us
      parent = subcriteria.getParent();
    } else {
      path = StringHelper.unroot(path);
    }

    if (parent.equals(rootCriteria)) {
      // if its the root criteria, we are done
      return path;
    } else {
      // otherwise, recurse
      return getWholeAssociationPath((CriteriaImpl.Subcriteria) parent) + '.' + path;
    }
  }
 @Override
 public String getPropertyName(String propertyName) {
   if (propertyName.indexOf('.') > 0) {
     String root = StringHelper.root(propertyName);
     Criteria crit = getAliasedCriteria(root);
     if (crit != null) {
       return propertyName.substring(root.length() + 1);
     }
   }
   return propertyName;
 }
 @Override
 public String getSQLAlias(Criteria criteria, String propertyName) {
   if (propertyName.indexOf('.') > 0) {
     String root = StringHelper.root(propertyName);
     Criteria subcriteria = getAliasedCriteria(root);
     if (subcriteria != null) {
       return getSQLAlias(subcriteria);
     }
   }
   return getSQLAlias(criteria);
 }
예제 #4
0
  private void doToken(String token, QueryTranslatorImpl q) throws QueryException {
    if (q.isName(StringHelper.root(token))) { // path expression
      doPathExpression(q.unalias(token), q);
    } else if (token.startsWith(ParserHelper.HQL_VARIABLE_PREFIX)) { // named query parameter
      q.addNamedParameter(token.substring(1));
      appendToken(q, "?");
    } else {
      Queryable persister = q.getEntityPersisterUsingImports(token);
      if (persister != null) { // the name of a class
        final String discrim = persister.getDiscriminatorSQLValue();
        if (InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim)) {
          throw new QueryException("subclass test not allowed for null or not null discriminator");
        } else {
          appendToken(q, discrim);
        }
      } else {
        Object constant;
        if (token.indexOf('.') > -1
            && (constant =
                    ReflectHelper.getConstantValue(
                        token,
                        q.getFactory().getServiceRegistry().getService(ClassLoaderService.class)))
                != null) {
          Type type;
          try {
            type = q.getFactory().getTypeResolver().heuristicType(constant.getClass().getName());
          } catch (MappingException me) {
            throw new QueryException(me);
          }
          if (type == null) {
            throw new QueryException(QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + token);
          }
          try {
            //noinspection unchecked
            appendToken(
                q, ((LiteralType) type).objectToSQLString(constant, q.getFactory().getDialect()));
          } catch (Exception e) {
            throw new QueryException(QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + token, e);
          }
        } else { // anything else

          String negatedToken = negated ? NEGATIONS.get(token.toLowerCase(Locale.ROOT)) : null;
          if (negatedToken != null && (!betweenSpecialCase || !"or".equals(negatedToken))) {
            appendToken(q, negatedToken);
          } else {
            appendToken(q, token);
          }
        }
      }
    }
  }
예제 #5
0
 String unalias(String path) {
   String alias = StringHelper.root(path);
   String name = getAliasName(alias);
   if (name != null) return name + path.substring(alias.length());
   return path;
 }
  public void doSecondPass(Map persistentClasses) throws MappingException {
    // TODO add parameters checkings
    if (ann == null) return;
    ResultSetMappingDefinition definition = new ResultSetMappingDefinition(ann.name());
    LOG.debugf("Binding result set mapping: %s", definition.getName());

    int entityAliasIndex = 0;

    for (EntityResult entity : ann.entities()) {
      // TODO parameterize lock mode?
      List<FieldResult> properties = new ArrayList<FieldResult>();
      List<String> propertyNames = new ArrayList<String>();
      for (FieldResult field : entity.fields()) {
        // use an ArrayList cause we might have several columns per root property
        String name = field.name();
        if (name.indexOf('.') == -1) {
          // regular property
          properties.add(field);
          propertyNames.add(name);
        } else {
          /**
           * Reorder properties 1. get the parent property 2. list all the properties following the
           * expected one in the parent property 3. calculate the lowest index and insert the
           * property
           */
          PersistentClass pc = mappings.getClass(entity.entityClass().getName());
          if (pc == null) {
            throw new MappingException(
                "Entity not found "
                    + entity.entityClass().getName()
                    + " in SqlResultsetMapping "
                    + ann.name());
          }
          int dotIndex = name.lastIndexOf('.');
          String reducedName = name.substring(0, dotIndex);
          Iterator parentPropIter = getSubPropertyIterator(pc, reducedName);
          List followers = getFollowers(parentPropIter, reducedName, name);

          int index = propertyNames.size();
          int followersSize = followers.size();
          for (int loop = 0; loop < followersSize; loop++) {
            String follower = (String) followers.get(loop);
            int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
            index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
          }
          propertyNames.add(index, name);
          properties.add(index, field);
        }
      }

      Set<String> uniqueReturnProperty = new HashSet<String>();
      Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
      for (Object property : properties) {
        final FieldResult propertyresult = (FieldResult) property;
        final String name = propertyresult.name();
        if ("class".equals(name)) {
          throw new MappingException(
              "class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead");
        }

        if (uniqueReturnProperty.contains(name)) {
          throw new MappingException(
              "duplicate @FieldResult for property "
                  + name
                  + " on @Entity "
                  + entity.entityClass().getName()
                  + " in "
                  + ann.name());
        }
        uniqueReturnProperty.add(name);

        final String quotingNormalizedColumnName =
            mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(propertyresult.column());

        String key = StringHelper.root(name);
        ArrayList<String> intermediateResults = propertyResultsTmp.get(key);
        if (intermediateResults == null) {
          intermediateResults = new ArrayList<String>();
          propertyResultsTmp.put(key, intermediateResults);
        }
        intermediateResults.add(quotingNormalizedColumnName);
      }

      Map<String, String[]> propertyResults = new HashMap<String, String[]>();
      for (Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet()) {
        propertyResults.put(
            entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
      }

      if (!BinderHelper.isEmptyAnnotationValue(entity.discriminatorColumn())) {
        final String quotingNormalizedName =
            mappings
                .getObjectNameNormalizer()
                .normalizeIdentifierQuoting(entity.discriminatorColumn());
        propertyResults.put("class", new String[] {quotingNormalizedName});
      }

      if (propertyResults.isEmpty()) {
        propertyResults = java.util.Collections.emptyMap();
      }

      NativeSQLQueryRootReturn result =
          new NativeSQLQueryRootReturn(
              "alias" + entityAliasIndex++,
              entity.entityClass().getName(),
              propertyResults,
              LockMode.READ);
      definition.addQueryReturn(result);
    }

    for (ColumnResult column : ann.columns()) {
      definition.addQueryReturn(
          new NativeSQLQueryScalarReturn(
              mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(column.name()), null));
    }

    for (ConstructorResult constructorResult : ann.classes()) {
      List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>();
      for (ColumnResult columnResult : constructorResult.columns()) {
        columnReturns.add(
            new NativeSQLQueryScalarReturn(
                mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(columnResult.name()),
                null));
      }
      definition.addQueryReturn(
          new NativeSQLQueryConstructorReturn(constructorResult.targetClass(), columnReturns));
    }

    if (isDefault) {
      mappings.addDefaultResultSetMapping(definition);
    } else {
      mappings.addResultSetMapping(definition);
    }
  }
  public FromElement createCollection(
      QueryableCollection queryableCollection,
      String role,
      JoinType joinType,
      boolean fetchFlag,
      boolean indexed)
      throws SemanticException {
    if (!collection) {
      throw new IllegalStateException("FromElementFactory not initialized for collections!");
    }
    this.inElementsFunction = indexed;
    FromElement elem;
    this.queryableCollection = queryableCollection;
    collectionType = queryableCollection.getCollectionType();
    String roleAlias = fromClause.getAliasGenerator().createName(role);

    // Correlated subqueries create 'special' implied from nodes
    // because correlated subselects can't use an ANSI-style join
    boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied;
    if (explicitSubqueryFromElement) {
      String pathRoot = StringHelper.root(path);
      FromElement origin = fromClause.getFromElement(pathRoot);
      if (origin == null || origin.getFromClause() != fromClause) {
        implied = true;
      }
    }

    // super-duper-classic-parser-regression-testing-mojo-magic...
    if (explicitSubqueryFromElement && PathSeparatorNode.useThetaStyleImplicitJoins) {
      implied = true;
    }

    Type elementType = queryableCollection.getElementType();
    if (elementType.isEntityType()) {
      // A collection of entities...
      elem = createEntityAssociation(role, roleAlias, joinType);
    } else if (elementType.isComponentType()) {
      // A collection of components...
      JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
      elem = createCollectionJoin(joinSequence, roleAlias);
    } else {
      // A collection of scalar elements...
      JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
      elem = createCollectionJoin(joinSequence, roleAlias);
    }

    elem.setRole(role);
    elem.setQueryableCollection(queryableCollection);
    // Don't include sub-classes for implied collection joins or subquery joins.
    if (implied) {
      elem.setIncludeSubclasses(false);
    }

    if (explicitSubqueryFromElement) {
      // Treat explict from elements in sub-queries properly.
      elem.setInProjectionList(true);
    }

    if (fetchFlag) {
      elem.setFetch(true);
    }
    return elem;
  }
예제 #8
0
 public static String getAlias(String path) {
   return StringHelper.root(path);
 }