net.kaczmarzyk.spring.data.jpa.domain.JoinFetch Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of specification-arg-resolver Show documentation
Show all versions of specification-arg-resolver Show documentation
An alternative API for filtering data with Spring MVC and Spring Data JPA.
This library provides a custom HandlerMethodArgumentResolver that transforms HTTP parameters
into a Specification object ready to use with Spring Data repositories.
/**
* Copyright 2014-2022 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 net.kaczmarzyk.spring.data.jpa.domain;
import net.kaczmarzyk.spring.data.jpa.utils.QueryContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import static net.kaczmarzyk.spring.data.jpa.utils.JoinPathUtils.pathToJoinContainsAlias;
import static net.kaczmarzyk.spring.data.jpa.utils.JoinPathUtils.pathToJoinSplittedByDot;
/**
* Extension to specification-arg-resolver to allow fetching collections in a specification query
*
* @author Tomasz Kaczmarzyk
* @author Gerald Humphries
* @author Jakub Radlica
*/
public class JoinFetch implements Specification, Fake {
private static final long serialVersionUID = 1L;
private QueryContext context;
private List pathsToFetch;
private String alias;
private JoinType joinType;
private boolean distinct;
public JoinFetch(QueryContext queryContext, String[] pathsToFetch, JoinType joinType, boolean distinct) {
this(queryContext, pathsToFetch, "", joinType, distinct);
}
public JoinFetch(QueryContext queryContext, String[] pathsToFetch, String alias, JoinType joinType, boolean distinct) {
this.context = queryContext;
this.pathsToFetch = Arrays.asList(pathsToFetch);
this.alias = alias;
this.joinType = joinType;
this.distinct = distinct;
if (!alias.isEmpty() && pathsToFetch.length != 1) {
throw new IllegalArgumentException(
"Join fetch alias can be defined only for join fetch with a single path! " +
"Remove alias from the annotation or repeat @JoinFetch annotation for every path and use unique alias for each join."
);
}
}
@Override
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
query.distinct(distinct);
if (!Number.class.isAssignableFrom(query.getResultType())) { // if it's not a count query, then just execute the fetch
if (pathsToFetch.size() == 1) {
String pathToFetch = pathsToFetch.get(0);
if (pathToJoinContainsAlias(pathToFetch)) {
String[] pathToJoinFetchOnSplittedByDot = pathToJoinSplittedByDot(pathToFetch);
String alias = pathToJoinFetchOnSplittedByDot[0];
String path = pathToJoinFetchOnSplittedByDot[1];
Fetch, ?> evaluatedJoinFetchForGivenAlias = context.getEvaluatedJoinFetch(alias);
if(evaluatedJoinFetchForGivenAlias == null) {
throw new IllegalArgumentException(
"Join fetch definition with alias: '" + alias + "' not found! " +
"Make sure that join with the alias '" + alias +"' is defined before the join with path: '" + pathToFetch + "'"
);
}
Fetch,?> joinFetch = evaluatedJoinFetchForGivenAlias.fetch(path, joinType);
if (StringUtils.isNotBlank(this.alias)) {
context.putEvaluatedJoinFetch(this.alias, joinFetch);
}
} else {
Fetch
© 2015 - 2024 Weber Informatics LLC | Privacy Policy