FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
    FromElement elem;

    implied =
        true; // TODO: always true for now, but not if we later decide to support elements() in the
              // from clause
    inElementsFunction = true;
    Type elementType = queryableCollection.getElementType();
    if (!elementType.isEntityType()) {
      throw new IllegalArgumentException(
          "Cannot create element join for a collection of non-entities!");
    }
    this.queryableCollection = queryableCollection;
    SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
    FromElement destination = null;
    String tableAlias = null;
    EntityPersister entityPersister = queryableCollection.getElementPersister();
    tableAlias = fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
    String associatedEntityName = entityPersister.getEntityName();
    EntityPersister targetEntityPersister = sfh.requireClassPersister(associatedEntityName);
    // Create the FROM element for the target (the elements of the collection).
    destination =
        createAndAddFromElement(
            associatedEntityName,
            classAlias,
            targetEntityPersister,
            (EntityType) queryableCollection.getElementType(),
            tableAlias);
    // If the join is implied, then don't include sub-classes on the element.
    if (implied) {
      destination.setIncludeSubclasses(false);
    }
    fromClause.addCollectionJoinFromElementByPath(path, destination);
    //		origin.addDestination(destination);
    // Add the query spaces.
    fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces());

    CollectionType type = queryableCollection.getCollectionType();
    String role = type.getRole();
    String roleAlias = origin.getTableAlias();

    String[] targetColumns = sfh.getCollectionElementColumns(role, roleAlias);
    AssociationType elementAssociationType = sfh.getElementAssociationType(type);

    // Create the join element under the from element.
    int joinType = JoinFragment.INNER_JOIN;
    JoinSequence joinSequence =
        sfh.createJoinSequence(
            implied, elementAssociationType, tableAlias, joinType, targetColumns);
    elem = initializeJoin(path, destination, joinSequence, targetColumns, origin, false);
    elem.setUseFromFragment(
        true); // The associated entity is implied, but it must be included in the FROM.
    elem.setCollectionTableAlias(roleAlias); // The collection alias is the role.
    return elem;
  }
  private CriteriaInfoProvider getPathInfo(String path) {
    StringTokenizer tokens = new StringTokenizer(path, ".");
    String componentPath = "";

    // start with the 'rootProvider'
    CriteriaInfoProvider provider = nameCriteriaInfoMap.get(rootEntityName);

    while (tokens.hasMoreTokens()) {
      componentPath += tokens.nextToken();
      Type type = provider.getType(componentPath);
      if (type.isAssociationType()) {
        // CollectionTypes are always also AssociationTypes - but there's not always an associated
        // entity...
        AssociationType atype = (AssociationType) type;
        CollectionType ctype = type.isCollectionType() ? (CollectionType) type : null;
        Type elementType = (ctype != null) ? ctype.getElementType(sessionFactory) : null;
        // is the association a collection of components or value-types? (i.e a colloction of valued
        // types?)
        if (ctype != null && elementType.isComponentType()) {
          provider =
              new ComponentCollectionCriteriaInfoProvider(
                  helper.getCollectionPersister(ctype.getRole()));
        } else if (ctype != null && !elementType.isEntityType()) {
          provider = new ScalarCollectionCriteriaInfoProvider(helper, ctype.getRole());
        } else {
          provider =
              new EntityCriteriaInfoProvider(
                  (Queryable)
                      sessionFactory.getEntityPersister(
                          atype.getAssociatedEntityName(sessionFactory)));
        }

        componentPath = "";
      } else if (type.isComponentType()) {
        if (!tokens.hasMoreTokens()) {
          throw new QueryException(
              "Criteria objects cannot be created directly on components.  Create a criteria on owning entity and use a dotted property to access component property: "
                  + path);
        } else {
          componentPath += '.';
        }
      } else {
        throw new QueryException("not an association: " + componentPath);
      }
    }

    return provider;
  }
Example #3
0
  /**
   * Initialize the role of the collection.
   *
   * @param collection The collection to be updated by reachability.
   * @param type The type of the collection.
   * @param entity The owner of the collection.
   * @param session The session from which this request originates
   */
  public static void processReachableCollection(
      PersistentCollection collection,
      CollectionType type,
      Object entity,
      SessionImplementor session) {

    collection.setOwner(entity);

    CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(collection);

    if (ce == null) {
      // refer to comment in StatefulPersistenceContext.addCollection()
      throw new HibernateException(
          "Found two representations of same collection: " + type.getRole());
    }

    // The CollectionEntry.isReached() stuff is just to detect any silly users
    // who set up circular or shared references between/to collections.
    if (ce.isReached()) {
      // We've been here before
      throw new HibernateException("Found shared references to a collection: " + type.getRole());
    }
    ce.setReached(true);

    SessionFactoryImplementor factory = session.getFactory();
    CollectionPersister persister = factory.getCollectionPersister(type.getRole());
    ce.setCurrentPersister(persister);
    ce.setCurrentKey(
        type.getKeyOfOwner(entity, session)); // TODO: better to pass the id in as an argument?

    if (LOG.isDebugEnabled()) {
      if (collection.wasInitialized())
        LOG.debugf(
            "Collection found: %s, was: %s (initialized)",
            MessageHelper.collectionInfoString(persister, ce.getCurrentKey(), factory),
            MessageHelper.collectionInfoString(
                ce.getLoadedPersister(), ce.getLoadedKey(), factory));
      else
        LOG.debugf(
            "Collection found: %s, was: %s (uninitialized)",
            MessageHelper.collectionInfoString(persister, ce.getCurrentKey(), factory),
            MessageHelper.collectionInfoString(
                ce.getLoadedPersister(), ce.getLoadedKey(), factory));
    }

    prepareCollectionForUpdate(collection, ce, factory);
  }
 private boolean isCollectionMatching(CollectionType type, String primarySideTableName) {
   // Find the reverse side collection and check if the table name and key columns are matching
   // what we have on the main side
   String collectionRole = type.getRole();
   CollectionPhysicalModel reverseCollectionPersister =
       (CollectionPhysicalModel) session.getFactory().getCollectionPersister(collectionRole);
   boolean isSameTable = primarySideTableName.equals(reverseCollectionPersister.getTableName());
   return isSameTable
       && Arrays.equals(keyColumnNames, reverseCollectionPersister.getKeyColumnNames());
 }
 /**
  * Iterate just the elements of the collection that are already there. Don't load any new elements
  * from the database.
  */
 public static Iterator getLoadedElementsIterator(
     SessionImplementor session, CollectionType collectionType, Object collection) {
   if (collectionIsInitialized(collection)) {
     // handles arrays and newly instantiated collections
     return collectionType.getElementsIterator(collection, session);
   } else {
     // does not handle arrays (thats ok, cos they can't be lazy)
     // or newly instantiated collections, so we can do the cast
     return ((PersistentCollection) collection).queuedAdditionIterator();
   }
 }
    /**
     * For each of the fields contained in this {@link Locks} object, parse out the type and the
     * field name and store those as the key and value in the "value" argument.
     */
    public void fillRelationships(SessionFactoryImplementor sfi, Map<String, Relationship> value) {

      final Type[] types = cm.getPropertyTypes();
      for (int t = 0; t < types.length; t++) {

        final Type type = types[t];
        final String name = type.getName();

        String to = null;
        Relationship field = null;
        if (type instanceof EntityType) {
          final EntityType entType = (EntityType) type;
          to = entType.getAssociatedEntityName();
          field = new Relationship(cm.getPropertyNames()[t], false);

        } else if (types[t] instanceof CollectionType) {
          final CollectionType colType = (CollectionType) types[t];
          final Type elemType = colType.getElementType(sfi);
          if (!elemType.isEntityType()) {
            continue; // The case for count maps and other primitives.
          }
          to = elemType.getName();

          int open = name.indexOf("(");
          int close = name.lastIndexOf(")");
          String role = name.substring(open + 1, close);
          int dot = role.lastIndexOf(".");
          field = new Relationship(role.substring(dot + 1), true);
        }

        if (to != null && field != null) {
          Map<String, ClassMetadata> m = sfi.getAllClassMetadata();
          for (Class<?> c : Impl.hierarchy(m, to)) {
            value.put(c.getName(), field);
          }
        }
      }
    }
  public void evictCollection(Object value, CollectionType type) {

    final Object pc;
    if (type.hasHolder(getSession().getEntityMode())) {
      pc = getSession().getPersistenceContext().removeCollectionHolder(value);
    } else if (value instanceof PersistentCollection) {
      pc = value;
    } else {
      return; // EARLY EXIT!
    }

    PersistentCollection collection = (PersistentCollection) pc;
    if (collection.unsetSession(getSession())) evictCollection(collection);
  }
  Object processCollection(Object collection, CollectionType type) throws HibernateException {

    if (collection == CollectionType.UNFETCHED_COLLECTION) {
      return null;
    }

    if (collection != null) {
      final PersistentCollection coll;
      if (type.hasHolder()) {
        coll = getSession().getPersistenceContext().getCollectionHolder(collection);
      } else {
        coll = (PersistentCollection) collection;
      }

      Collections.processReachableCollection(coll, type, owner, getSession());
    }

    return null;
  }
 /**
  * Given a collection, get an iterator of all its children, loading them from the database if
  * necessary.
  *
  * @param session The session within which the cascade is occuring.
  * @param collectionType The mapping type of the collection.
  * @param collection The collection instance.
  * @return The children iterator.
  */
 private static Iterator getAllElementsIterator(
     EventSource session, CollectionType collectionType, Object collection) {
   return collectionType.getElementsIterator(collection, session);
 }