@SuppressWarnings("unchecked")
    private <T> Path<T> shorten(Path<T> path, List<Path<?>> paths) {
        PathMetadata metadata = path.getMetadata();
        if (metadata.isRoot() || paths.contains(path)) {
            return path;
        } else if (aliases.containsKey(path)) {
            return (Path<T>) aliases.get(path);
        } else if (metadata.getPathType() == PathType.COLLECTION_ANY) {
            return (Path<T>) shorten(metadata.getParent(), paths);
        } else if (!isEntityPath(path)) {
            Path<?> parent = shorten(metadata.getParent(), paths);
            if (parent.equals(metadata.getParent())) {
                return path;
            } else {
                return ExpressionUtils.path(path.getType(),
                        new PathMetadata(parent, metadata.getElement(), metadata.getPathType()));
            }
        } else if (metadata.getParent().getMetadata().isRoot()) {
            Class<T> type = getElementTypeOrType(path);
            Path<T> newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(path));
            leftJoin(path, newPath);
            return newPath;
        } else {
            Class<T> type = getElementTypeOrType(path);
            Path<?> parent = shorten(metadata.getParent(), paths);
            Path<T> oldPath = ExpressionUtils.path(path.getType(),
                    new PathMetadata(parent, metadata.getElement(), metadata.getPathType()));
            Path<T> newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(oldPath));
            aliases.put(path, newPath);
            leftJoin(oldPath, newPath);
            return newPath;
        }
    }
{@code JPAQueryMixin} extends {@link QueryMixin} to support JPQL join construction

@author tiwe

@param <T>
querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryMixin.java