public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
      throws HibernateException {
    String entityName = criteriaQuery.getEntityName(criteria, propertyName);
    String actualPropertyName = criteriaQuery.getPropertyName(propertyName);
    String sqlAlias = criteriaQuery.getSQLAlias(criteria, propertyName);

    SessionFactoryImplementor factory = criteriaQuery.getFactory();
    QueryableCollection collectionPersister =
        getQueryableCollection(entityName, actualPropertyName, factory);

    String[] collectionKeys = collectionPersister.getKeyColumnNames();
    String[] ownerKeys =
        ((Loadable) factory.getEntityPersister(entityName)).getIdentifierColumnNames();

    String innerSelect =
        "(select 1 from "
            + collectionPersister.getTableName()
            + " where "
            + new ConditionFragment()
                .setTableAlias(sqlAlias)
                .setCondition(ownerKeys, collectionKeys)
                .toFragmentString()
            + ")";

    return excludeEmpty() ? "exists " + innerSelect : "not exists " + innerSelect;
  }
 private String getPathEntityName(String path) {
   Queryable persister = (Queryable) sessionFactory.getEntityPersister(rootEntityName);
   StringTokenizer tokens = new StringTokenizer(path, ".");
   String componentPath = "";
   while (tokens.hasMoreTokens()) {
     componentPath += tokens.nextToken();
     Type type = persister.toType(componentPath);
     if (type.isAssociationType()) {
       AssociationType atype = (AssociationType) type;
       persister =
           (Queryable)
               sessionFactory.getEntityPersister(atype.getAssociatedEntityName(sessionFactory));
       componentPath = "";
     } else if (type.isComponentType()) {
       componentPath += '.';
     } else {
       throw new QueryException("not an association: " + componentPath);
     }
   }
   return persister.getEntityName();
 }
  protected QueryableCollection getQueryableCollection(
      String entityName, String propertyName, SessionFactoryImplementor factory)
      throws HibernateException {
    PropertyMapping ownerMapping = (PropertyMapping) factory.getEntityPersister(entityName);
    Type type = ownerMapping.toType(propertyName);
    if (!type.isCollectionType()) {
      throw new MappingException(
          "Property path ["
              + entityName
              + "."
              + propertyName
              + "] does not reference a collection");
    }

    String role = ((CollectionType) type).getRole();
    try {
      return (QueryableCollection) factory.getCollectionPersister(role);
    } catch (ClassCastException cce) {
      throw new QueryException("collection role is not queryable: " + role);
    } catch (Exception e) {
      throw new QueryException("collection role not found: " + role);
    }
  }
  private Object assembleCacheEntry(
      final CacheEntry entry,
      final Serializable id,
      final EntityPersister persister,
      final LoadEvent event)
      throws HibernateException {

    final Object optionalObject = event.getInstanceToLoad();
    final EventSource session = event.getSession();
    final SessionFactoryImplementor factory = session.getFactory();

    if (log.isTraceEnabled()) {
      log.trace(
          "assembling entity from second-level cache: "
              + MessageHelper.infoString(persister, id, factory));
    }

    EntityPersister subclassPersister = factory.getEntityPersister(entry.getSubclass());
    Object result =
        optionalObject == null ? session.instantiate(subclassPersister, id) : optionalObject;

    // make it circular-reference safe
    TwoPhaseLoad.addUninitializedCachedEntity(
        new EntityKey(id, subclassPersister, session.getEntityMode()),
        result,
        subclassPersister,
        LockMode.NONE,
        entry.areLazyPropertiesUnfetched(),
        entry.getVersion(),
        session);

    Type[] types = subclassPersister.getPropertyTypes();
    Object[] values =
        entry.assemble(
            result,
            id,
            subclassPersister,
            session.getInterceptor(),
            session); // intializes result by side-effect
    TypeFactory.deepCopy(
        values, types, subclassPersister.getPropertyUpdateability(), values, session);

    Object version = Versioning.getVersion(values, subclassPersister);
    if (log.isTraceEnabled()) log.trace("Cached Version: " + version);

    final PersistenceContext persistenceContext = session.getPersistenceContext();
    persistenceContext.addEntry(
        result,
        Status.MANAGED,
        values,
        null,
        id,
        version,
        LockMode.NONE,
        true,
        subclassPersister,
        false,
        entry.areLazyPropertiesUnfetched());
    subclassPersister.afterInitialize(result, entry.areLazyPropertiesUnfetched(), session);
    persistenceContext.initializeNonLazyCollections();
    // upgrade the lock if necessary:
    // lock(result, lockMode);

    // PostLoad is needed for EJB3
    // TODO: reuse the PostLoadEvent...
    PostLoadEvent postLoadEvent =
        new PostLoadEvent(session).setEntity(result).setId(id).setPersister(persister);
    PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
    for (int i = 0; i < listeners.length; i++) {
      listeners[i].onPostLoad(postLoadEvent);
    }

    return result;
  }
 private PropertyMapping getPropertyMapping(String entityName) throws MappingException {
   return (PropertyMapping) sessionFactory.getEntityPersister(entityName);
 }