Skip to content

Commit

Permalink
Push from SCM (2022-12-08)
Browse files Browse the repository at this point in the history
  • Loading branch information
locke-chappel committed Dec 8, 2022
1 parent 850f3b9 commit 54095a6
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 320 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${org.hibernate.version}</version>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.github.lc.oss.commons.jpa;

import java.util.ArrayList;

import com.github.lc.oss.commons.serialization.Jsonable;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;

public abstract class AbstractQueryBuilder<Type extends Jsonable> {
public CriteriaQuery<Type> forData(SearchCriteria searchCriteria, CriteriaBuilder criteriaBuilder) {
QueryInfo info = this.build(searchCriteria, criteriaBuilder, false);
CriteriaQuery<Type> query = info.getQuery();
query.select(info.getSelection());
return query;
}

public CriteriaQuery<Long> forCount(SearchCriteria searchCriteria, CriteriaBuilder criteriaBuilder) {
QueryInfo info = this.build(searchCriteria, criteriaBuilder, true);
CriteriaQuery<Long> query = info.getQuery();
query.orderBy(new ArrayList<>());
query.select(info.getSelection());
return query;
}

protected abstract <T> QueryInfo build(SearchCriteria searchCriteria, CriteriaBuilder criteriaBuilder, boolean forCount);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,19 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.github.lc.oss.commons.serialization.Jsonable;
import com.github.lc.oss.commons.serialization.PagedResult;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Order;
import jakarta.persistence.criteria.Predicate;

public abstract class AbstractSearchService {
private static final char SQL_ESCAPE_CHAR = '\\';
private static final List<String> SQL_TO_ESCAPE = Collections.unmodifiableList(Arrays.asList( //
Expand All @@ -46,18 +42,22 @@ public abstract class AbstractSearchService {
@PersistenceContext
private EntityManager entityManager;

protected <Type extends Jsonable> PagedResult<Type> getPage(CriteriaQuery<Type> query, Root<?> root, int pageSize, int pageNumber) {
TypedQuery<Type> typedQuery = this.getEntityManager().createQuery(query);
typedQuery.setFirstResult(pageSize * pageNumber);
typedQuery.setMaxResults(pageSize);
List<Type> result = typedQuery.getResultList();
protected <Type extends Jsonable> PagedResult<Type> getPage(AbstractQueryBuilder<Type> queryBuilder, SearchCriteria searchCriteria) {
CriteriaBuilder cb = this.getCriteriaBuilder();
CriteriaQuery<Type> dataQuery = queryBuilder.forData(searchCriteria, cb);
CriteriaQuery<Long> countQuery = queryBuilder.forCount(searchCriteria, cb);

TypedQuery<Type> typedDataQuery = this.getEntityManager().createQuery(dataQuery);
typedDataQuery.setFirstResult(searchCriteria.getPageSize() * searchCriteria.getPageNumber());
typedDataQuery.setMaxResults(searchCriteria.getPageSize());
List<Type> result = typedDataQuery.getResultList();

long total = this.count(query, root);
TypedQuery<Long> typedCountQuery = this.getEntityManager().createQuery(countQuery);
long total = typedCountQuery.getSingleResult().longValue();

PagedResult<Type> results = new PagedResult<>();
results.setData(result);
results.setTotal(total);
results.setData(result);
return results;
}

Expand Down Expand Up @@ -113,58 +113,6 @@ protected <Type> void where(CriteriaQuery<Type> query, Collection<Predicate> whe
query.where(wheres.toArray(new Predicate[wheres.size()]));
}

/*
* count and associated methods from https://stackoverflow.com/a/10557039
*/
protected long count(final CriteriaQuery<?> selectQuery, Root<?> root) {
CriteriaQuery<Long> query = this.createCountQuery(selectQuery, root);
return this.getEntityManager().createQuery(query).getSingleResult();
}

private CriteriaQuery<Long> createCountQuery(final CriteriaQuery<?> criteria, final Root<?> root) {
CriteriaBuilder cb = this.getCriteriaBuilder();
final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
/*
* Modified - original got class from criteria but that may not be an entity
* when using projections
*/
final Root<?> countRoot = countQuery.from(root.getJavaType());

this.doJoins(root.getJoins(), countRoot);
this.doJoinsOnFetches(root.getFetches(), countRoot);

countQuery.select(cb.count(countRoot));
Predicate where = criteria.getRestriction();
if (where != null) {
countQuery.where(where);
}

countRoot.alias(root.getAlias());

return countQuery.distinct(criteria.isDistinct());
}

@SuppressWarnings("unchecked")
private void doJoinsOnFetches(Set<? extends Fetch<?, ?>> joins, Root<?> root) {
this.doJoins((Set<? extends Join<?, ?>>) joins, root);
}

private void doJoins(Set<? extends Join<?, ?>> joins, Root<?> root) {
for (Join<?, ?> join : joins) {
Join<?, ?> joined = root.join(join.getAttribute().getName(), join.getJoinType());
joined.alias(join.getAlias());
this.doJoins(join.getJoins(), joined);
}
}

private void doJoins(Set<? extends Join<?, ?>> joins, Join<?, ?> root) {
for (Join<?, ?> join : joins) {
Join<?, ?> joined = root.join(join.getAttribute().getName(), join.getJoinType());
joined.alias(join.getAlias());
this.doJoins(join.getJoins(), joined);
}
}

protected String escape(String str) {
return this.escape(str, false);
}
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/com/github/lc/oss/commons/jpa/QueryInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.github.lc.oss.commons.jpa;

import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Selection;

@SuppressWarnings("unchecked")
public class QueryInfo {
private Selection<?> selection;
private CriteriaQuery<?> query;

public <T> Selection<T> getSelection() {
return (Selection<T>) this.selection;
}

public void setSelection(Selection<?> selection) {
this.selection = selection;
}

public <T> CriteriaQuery<T> getQuery() {
return (CriteriaQuery<T>) this.query;
}

public void setQuery(CriteriaQuery<?> query) {
this.query = query;
}
}
3 changes: 2 additions & 1 deletion src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
requires com.github.lc.oss.commons.serialization;
requires com.github.lc.oss.commons.util;

requires java.persistence;
requires transitive jakarta.persistence;
requires org.hibernate.orm.core;

exports com.github.lc.oss.commons.jpa;
}
Loading

0 comments on commit 54095a6

Please sign in to comment.