org.dynamoframework.dao.impl.BaseDaoImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dynamo-impl Show documentation
Show all versions of dynamo-impl Show documentation
Dynamo Framework implementation project.
package org.dynamoframework.dao.impl;
/*-
* #%L
* Dynamo Framework
* %%
* Copyright (C) 2014 - 2024 Open Circle Solutions
* %%
* 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.
* #L%
*/
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.jpa.impl.JPADeleteClause;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAUpdateClause;
import jakarta.persistence.*;
import jakarta.persistence.criteria.CriteriaQuery;
import org.dynamoframework.dao.*;
import org.dynamoframework.domain.AbstractEntity;
import org.dynamoframework.domain.model.EntityModelFactory;
import org.dynamoframework.exception.OCSRuntimeException;
import org.dynamoframework.filter.Filter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
import java.util.stream.Collectors;
/**
* Base class for all DAO implementations
*
* @param type parameter, the type of the primary key of the domain object
* @param type parameter, the entity class
* @author bas.rutten
*/
public abstract class BaseDaoImpl> implements BaseDao {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private EntityModelFactory entityModelFactory;
/**
* Adds a parameter to a query but only if the provided value is not null
*
* @param query the query to add the parameter to
* @param name the name of the parameter
* @param value the value of the parameter
*/
protected void addParameter(Query query, String name, Object value) {
if (value != null) {
query.setParameter(name, value);
}
}
@Override
@SuppressWarnings("deprecation")
public long count() {
return createQuery().fetchCount();
}
@Override
public long count(Filter filter, boolean distinct) {
TypedQuery query = JpaQueryBuilder.createCountQuery(entityManager, getEntityClass(), filter, distinct);
return query.getSingleResult();
}
/**
* Creates a new JPADeleteClause for the entity
*
* @return the newly created JPADeleteClause
*/
protected JPADeleteClause createDeleteClause() {
return new JPADeleteClause(getEntityManager(), getDslRoot());
}
/**
* Creates a default query that simply retrieves instances of the domain class
*
* @return the newly created JPAQuery
*/
protected JPAQuery createQuery() {
JPAQuery query = new JPAQuery<>(entityManager);
query.from(getDslRoot());
return query;
}
/**
* Creates a new JPAUpdateClause for the entity
*
* @return the newly created JPAUpdateClause
*/
protected JPAUpdateClause createUpdateClause() {
return new JPAUpdateClause(getEntityManager(), getDslRoot());
}
@Override
public void delete(List list) {
list.forEach(this::delete);
}
@Override
public void delete(T entity) {
entity = entityManager.merge(entity);
entityManager.remove(entity);
}
@Override
public void deleteAll() {
this.delete(this.findAll());
}
@Override
public List fetch(Filter filter, FetchJoinInformation... joins) {
return fetch(filter, null, null, joins);
}
@Override
public List fetch(Filter filter, Pageable pageable, FetchJoinInformation... joins) {
return fetch(filter, pageable, pageable == null ? null : pageable.getSortOrders(), joins);
}
/**
* Executes a fetch query - watch out, paging combined with one-to-many joins
* leads to everything being calculated in-memory
*
* @param filter the filter to apply
* @param pageable object containing the paging data
* @param sortOrders list of sort orders that must be applied
* @param joins the joins to apply - if null then the default joins will be
* used
* @return a page of entities that match the filter
*/
private List fetch(Filter filter, Pageable pageable, SortOrders sortOrders, FetchJoinInformation... joins) {
TypedQuery query = JpaQueryBuilder.createSelectQuery(filter, entityManager, getEntityClass(),
(joins == null || joins.length == 0) ? getJoins() : joins,
sortOrders == null ? null : sortOrders.toArray());
if (pageable != null) {
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
}
return query.getResultList();
}
protected FetchJoinInformation[] getJoins() {
return entityModelFactory.getModel(getEntityClass())
.getFetchJoins().toArray(new FetchJoinInformation[0]);
}
protected FetchJoinInformation[] getDetailJoins() {
return entityModelFactory.getModel(getEntityClass())
.getDetailJoins().toArray(new FetchJoinInformation[0]);
}
@Override
public List fetch(Filter filter, SortOrders sortOrders, FetchJoinInformation... joins) {
return fetch(filter, null, sortOrders, joins);
}
@Override
public T fetchById(ID id, FetchJoinInformation... joins) {
TypedQuery query = JpaQueryBuilder.createFetchSingleObjectQuery(entityManager, getEntityClass(), id,
(joins != null && joins.length > 0) ? joins : getDetailJoins());
return getFirstValue(query.getResultList());
}
@Override
public List fetchByIds(List ids, Filter additionalFilter, SortOrders sortOrders,
FetchJoinInformation... joins) {
if (ids.isEmpty()) {
return Collections.emptyList();
}
TypedQuery query = JpaQueryBuilder.createFetchQuery(entityManager, getEntityClass(), ids, additionalFilter,
sortOrders, (joins != null && joins.length > 0) ? joins : getJoins());
return query.getResultList();
}
@Override
public List fetchByIds(List ids, SortOrders sortOrders, FetchJoinInformation... joins) {
return fetchByIds(ids, null, sortOrders, joins);
}
@Override
public T fetchByUniqueProperty(String propertyName, Object value, boolean caseSensitive,
FetchJoinInformation... joins) {
CriteriaQuery cq = JpaQueryBuilder.createUniquePropertyFetchQuery(entityManager, getEntityClass(),
(joins == null || joins.length == 0) ? getDetailJoins() : joins, propertyName, value, caseSensitive);
TypedQuery query = entityManager.createQuery(cq);
try {
return query.getSingleResult();
} catch (NoResultException ex) {
return null;
} catch (NonUniqueResultException ex) {
throw new OCSRuntimeException("Query for unique property returned multiple results", ex);
}
}
@Override
public List find(Filter filter) {
return fetch(filter, null, null, (FetchJoinInformation[]) null);
}
private List find(Filter filter, Pageable pageable, SortOrders sortOrders) {
TypedQuery query = JpaQueryBuilder.createSelectQuery(filter, entityManager, getEntityClass(), null,
sortOrders == null ? null : sortOrders.toArray());
if (pageable != null) {
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
}
return query.getResultList();
}
@Override
public List find(Filter filter, SortOrder... orders) {
return fetch(filter, null, new SortOrders(orders), (FetchJoinInformation[]) null);
}
@Override
public List findAll() {
return findAll((SortOrder[]) null);
}
@Override
public List findAll(SortOrder... sortOrders) {
return find(null, null, new SortOrders(sortOrders));
}
@Override
public T findById(ID id) {
return entityManager.find(getEntityClass(), id);
}
@Override
public T findByUniqueProperty(String propertyName, Object value, boolean caseSensitive) {
CriteriaQuery cq = JpaQueryBuilder.createUniquePropertyQuery(entityManager, getEntityClass(), propertyName,
value, caseSensitive);
TypedQuery query = entityManager.createQuery(cq);
try {
return query.getSingleResult();
} catch (NoResultException ex) {
return null;
} catch (NonUniqueResultException ex) {
throw new OCSRuntimeException("Query for unique property returned multiple results", ex);
}
}
@Override
@SuppressWarnings("unchecked")
public List findDistinctValues(Filter filter, String distinctField, Class elementType, SortOrder... orders) {
TypedQuery query = JpaQueryBuilder.createDistinctQuery(filter, entityManager, getEntityClass(),
distinctField, orders);
return query.getResultList().stream().map(t -> t.get(0)).filter(Objects::nonNull).map(o -> (S) o)
.toList();
}
@Override
@SuppressWarnings("unchecked")
public List findDistinctInCollectionTable(String tableName, String distinctField, Class elementType) {
String query = "select distinct %s from %s".formatted(distinctField, tableName);
return getEntityManager().createNativeQuery(query).getResultList();
}
@Override
@SuppressWarnings("unchecked")
public List findIds(Filter filter, Integer maxResults, SortOrder... sortOrders) {
TypedQuery query = JpaQueryBuilder.createIdQuery(entityManager, getEntityClass(), filter, sortOrders);
if (maxResults != null) {
query = query.setMaxResults(maxResults);
}
return query.getResultList().stream().map(tuple -> tuple.get(0)).map(o -> (ID) o).collect(Collectors.toList());
}
@Override
public List findIds(Filter filter, SortOrder... sortOrders) {
return findIds(filter, null, sortOrders);
}
@Override
public void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
/**
* Returns the query DSL root
*
* @return the DSL root object
*/
protected abstract EntityPathBase getDslRoot();
protected EntityManager getEntityManager() {
return entityManager;
}
// /**
// * Returns the fetch joins that must be included in a query to fetch the IDs.
// * This method return an empty array by default - override when needed
// *
// * @return the fetch joins
// */
// protected FetchJoinInformation[] getFetchJoins() {
// return new FetchJoinInformation[]{};
// }
/**
* Returns the first value of a list
*
* @param list the list
* @return the first value of the list, or null
if this does not
* exist
*/
protected T getFirstValue(List list) {
return list != null && !list.isEmpty() ? list.get(0) : null;
}
/**
* Returns an Optional containing the first value of the provided list
*
* @param list the list to select the first value from
* @return the Optional
*/
protected Optional getFirstValueOptional(List list) {
return Optional.ofNullable(getFirstValue(list));
}
@Override
public List save(List list) {
List result = new ArrayList<>();
for (T entity : list) {
result.add(this.save(entity));
}
return result;
}
@Override
public T save(T entity) {
if (entity.getId() == null) {
entityManager.persist(entity);
} else {
entity = entityManager.merge(entity);
}
return entity;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy