@SuppressWarnings("unchecked")
  private CriteriaQueryImpl<Y> generateOwnerSelectCriteria(
      final MetamodelImpl metamodel,
      final CriteriaBuilderImpl cb,
      Class<Y> bindableType,
      EntityTypeImpl<Y> entity) {
    final CriteriaQueryImpl<Y> q = cb.createQuery(bindableType);
    q.internal();

    final EntityTypeImpl<?> type = (EntityTypeImpl<?>) this.getRoot().getType();

    final RootImpl<?> r = q.from(type);
    r.alias(BatooUtils.acronym(type.getName()).toLowerCase());

    final Iterator<String> pathIterator = Splitter.on(".").split(this.getPath()).iterator();

    // Drop the root part
    pathIterator.next();

    AbstractJoin<?, ?> join = null;
    while (pathIterator.hasNext()) {
      join = join == null ? r.<Y>join(pathIterator.next()) : join.join(pathIterator.next());
    }

    q.select((Selection<? extends Y>) join);

    entity.prepareEagerJoins(join, 0, this);

    return this.selectCriteria = q.where(cb.equal(r, cb.parameter(type.getJavaType())));
  }
  private CriteriaQueryImpl<Y> generateMappedSelectCriteria(
      MetamodelImpl metamodel,
      CriteriaBuilderImpl cb,
      Class<Y> bindableType,
      EntityTypeImpl<Y> entity) {
    final CriteriaQueryImpl<Y> q = cb.createQuery(bindableType);
    q.internal();

    final RootImpl<Y> r = q.from(entity);
    r.alias(BatooUtils.acronym(entity.getName()).toLowerCase());

    q.select(r);

    final Iterator<String> pathIterator =
        Splitter.on(".").split(this.getInverse().getPath()).iterator();

    // Drop the root part
    pathIterator.next();

    AbstractPath<?> path = null;
    while (pathIterator.hasNext()) {
      path = path == null ? r.get(pathIterator.next()) : path.get(pathIterator.next());
    }

    entity.prepareEagerJoins(r, 0, this);

    final ParameterExpressionImpl<?> pe = cb.parameter(this.getInverse().getJavaType());
    final PredicateImpl predicate = cb.equal(path, pe);
    return this.selectCriteria = q.where(predicate);
  }