com.jaxio.jpa.querybyexample.ByExampleUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jpa-querybyexample Show documentation
Show all versions of jpa-querybyexample Show documentation
This API allows you to construct Query By Example using the JPA 2 Criteria API.
The newest version!
/*
* Copyright 2015 JAXIO http://www.jaxio.com
*
* 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 com.jaxio.jpa.querybyexample;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.*;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.emptyList;
import static javax.persistence.metamodel.Attribute.PersistentAttributeType.*;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
/**
* Helper to create predicate by example. It processes associated entities (1 level deep).
*/
@Named
@Singleton
public class ByExampleUtil {
private static final Logger log = LoggerFactory.getLogger(ByExampleUtil.class);
@Inject
private JpaUtil jpaUtil;
@PersistenceContext
private EntityManager em;
public > Predicate byExampleOnEntity(Root rootPath, T entityValue, CriteriaBuilder builder, SearchParameters sp) {
if (entityValue == null) {
return null;
}
Class type = rootPath.getModel().getBindableJavaType();
ManagedType mt = em.getMetamodel().entity(type);
List predicates = newArrayList();
predicates.addAll(byExample(mt, rootPath, entityValue, sp, builder));
predicates.addAll(byExampleOnCompositePk(rootPath, entityValue, sp, builder));
predicates.addAll(byExampleOnXToOne(mt, rootPath, entityValue, sp, builder)); // 1 level deep only
predicates.addAll(byExampleOnXToMany(mt, rootPath, entityValue, sp, builder));
return jpaUtil.concatPredicate(sp, builder, predicates);
}
protected > List byExampleOnCompositePk(Root root, T entity, SearchParameters sp, CriteriaBuilder builder) {
String compositePropertyName = jpaUtil.compositePkPropertyName(entity);
if (compositePropertyName == null) {
return emptyList();
} else {
return newArrayList(byExampleOnEmbeddable(root.get(compositePropertyName), entity.getId(), sp, builder));
}
}
public Predicate byExampleOnEmbeddable(Path embeddablePath, E embeddableValue, SearchParameters sp, CriteriaBuilder builder) {
if (embeddableValue == null) {
return null;
}
Class type = embeddablePath.getModel().getBindableJavaType();
ManagedType mt = em.getMetamodel().embeddable(type); // note: calling .managedType() does not work
return jpaUtil.andPredicate(builder, byExample(mt, embeddablePath, embeddableValue, sp, builder));
}
/*
* Add a predicate for each simple property whose value is not null.
*/
public List byExample(ManagedType mt, Path mtPath, T mtValue, SearchParameters sp, CriteriaBuilder builder) {
List predicates = newArrayList();
for (SingularAttribute super T, ?> attr : mt.getSingularAttributes()) {
if (attr.getPersistentAttributeType() == MANY_TO_ONE //
|| attr.getPersistentAttributeType() == ONE_TO_ONE //
|| attr.getPersistentAttributeType() == EMBEDDED) {
continue;
}
Object attrValue = jpaUtil.getValue(mtValue, attr);
if (attrValue != null) {
if (attr.getJavaType() == String.class) {
if (isNotEmpty((String) attrValue)) {
predicates.add(jpaUtil.stringPredicate(mtPath.get(jpaUtil.stringAttribute(mt, attr)), attrValue, sp, builder));
}
} else {
predicates.add(builder.equal(mtPath.get(jpaUtil.attribute(mt, attr)), attrValue));
}
}
}
return predicates;
}
/*
* Invoke byExample method for each not null x-to-one association when their pk is not set. This allows you to search entities based on an associated
* entity's properties value.
*/
@SuppressWarnings("unchecked")
public , M2O extends Identifiable>> List byExampleOnXToOne(ManagedType mt, Root mtPath, T mtValue,
SearchParameters sp, CriteriaBuilder builder) {
List predicates = newArrayList();
for (SingularAttribute super T, ?> attr : mt.getSingularAttributes()) {
if (attr.getPersistentAttributeType() == MANY_TO_ONE || attr.getPersistentAttributeType() == ONE_TO_ONE) {
M2O m2oValue = (M2O) jpaUtil.getValue(mtValue, mt.getAttribute(attr.getName()));
Class m2oType = (Class) attr.getBindableJavaType();
Path m2oPath = (Path) mtPath.get(attr);
ManagedType m2oMt = em.getMetamodel().entity(m2oType);
if (m2oValue != null) {
if (m2oValue.isIdSet()) { // we have an id, let's restrict only on this field
predicates.add(builder.equal(m2oPath.get("id"), m2oValue.getId()));
} else {
predicates.addAll(byExample(m2oMt, m2oPath, m2oValue, sp, builder));
}
}
}
}
return predicates;
}
/*
* Construct a join predicate on collection (eg many to many, List)
*/
public List byExampleOnXToMany(ManagedType mt, Root mtPath, T mtValue, SearchParameters sp, CriteriaBuilder builder) {
List predicates = newArrayList();
for (PluralAttribute super T, ?, ?> pa : mt.getPluralAttributes()) {
if (pa.getCollectionType() == PluralAttribute.CollectionType.LIST) {
List> values = (List>) jpaUtil.getValue(mtValue, mt.getAttribute(pa.getName()));
if (values != null && !values.isEmpty()) {
if (sp.getUseAndInXToMany()) {
if (values.size() > 3) {
log.warn("Please note that using AND restriction on an Many to Many relationship requires as many joins as values");
}
for (Object value : values) {
ListJoin join = mtPath.join(mt.getList(pa.getName()));
predicates.add(join.in(value));
}
} else {
ListJoin join = mtPath.join(mt.getList(pa.getName()));
predicates.add(join.in(values));
}
}
}
}
return predicates;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy