/*
* Copyright 2008-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.flower.common.repository;
import com.mysema.query.jpa.JPQLQuery;
import com.mysema.query.jpa.impl.JPAQuery;
import com.mysema.query.types.*;
import de.flower.common.util.ReflectionUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.QueryDslJpaRepository;
import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;
/**
* Adds support for prefetching associations.
*
* @author flower
*/
public class ExtendedQueryDslJpaRepository<T, ID extends Serializable> extends QueryDslJpaRepository<T, ID> {
private EntityManager em;
public ExtendedQueryDslJpaRepository(JpaEntityInformation<T, ID> entityMetadata, EntityManager entityManager) {
super(entityMetadata, entityManager);
this.em = entityManager;
}
public List<T> findAll(final Predicate predicate, final Path<?>... fetchAttributes) {
return createQuery(fetchAttributes).where(predicate).list(getPath());
}
public Page<T> findAll(final Predicate predicate, Pageable pageable, final Path<?>... fetchAttributes) {
JPQLQuery countQuery = createQuery(predicate);
JPQLQuery query = applyPagination(createQuery(fetchAttributes).where(predicate), pageable);
return new PageImpl<T>(query.list(getPath()), pageable, countQuery.count());
}
public List<T> findAll(final Predicate predicate, final OrderSpecifier<?> order, final Path<?>... fetchAttributes) {
return createQuery(fetchAttributes).where(predicate).orderBy(order).list(getPath());
}
protected JPQLQuery createQuery(Path<?>... fetchAttributes) {
JPAQuery query = new JPAQuery(em).from(getPath());
if (fetchAttributes != null) {
for (Path<?> path : fetchAttributes) {
if (path instanceof EntityPath) {
query.leftJoin((EntityPath<?>) path).fetch();
} else if (path instanceof CollectionExpression) {
query.leftJoin((CollectionExpression<?, ?>) path).fetch();
} else {
throw new RuntimeException("Unknown path type [" + path + "].");
}
}
}
query.distinct(); // fetching one-to-many associations would multiply the result set.
return query;
}
private EntityPath<T> getPath() {
return (EntityPath<T>) ReflectionUtil.getField(this, "path");
}
}