AbstractGenericDAOImpl.java
/*
* Copyright 2010 James Pether Sörling
*
* 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.
*
* $Id$
* $HeadURL$
*/
package com.hack23.cia.service.data.impl;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
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.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.CacheMode;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import com.hack23.cia.service.data.api.AbstractGenericDAO;
import com.hack23.cia.service.data.impl.util.LoadHelper;
/**
* The Class AbstractGenericDAOImpl.
*
* @param <T>
* the generic type
* @param <I>
* the generic type
*/
abstract class AbstractGenericDAOImpl<T extends Serializable, I extends Serializable>
implements AbstractGenericDAO<T, I> {
/** The entity manager. */
@PersistenceContext(name = "ciaPersistenceUnit")
private EntityManager entityManager;
/** The criteria builder. */
private CriteriaBuilder criteriaBuilder;
/** The metamodel. */
private Metamodel metamodel;
/** The persistent class. */
private final Class<T> persistentClass;
/**
* Instantiates a new abstract generic dao impl.
*
* @param persistentClass
* the persistent class
*/
protected AbstractGenericDAOImpl(final Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
/**
* Adds the cache hints.
*
* @param typedQuery
* the typed query
* @param comment
* the comment
*/
protected final void addCacheHints(final TypedQuery<?> typedQuery, final String comment) {
typedQuery.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
typedQuery.setHint("org.hibernate.cacheable", Boolean.TRUE);
typedQuery.setHint("org.hibernate.comment", comment);
}
@Override
public final void delete(final T entity) {
getEntityManager().remove(entity);
}
@Override
public final T findFirstByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
final Root<T> root = criteriaQuery.from(getPersistentClass());
criteriaQuery.select(root);
final Predicate condition = criteriaBuilder.equal(root.get(property), value);
criteriaQuery.where(condition);
final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
addCacheHints(typedQuery, "findFirstByProperty");
final List<T> resultList = typedQuery.getResultList();
if (resultList.isEmpty()) {
return null;
} else {
return LoadHelper.recursiveInitialize(resultList.get(0));
}
}
@Override
public final List<T> findListByProperty(final Object[] values,
final SingularAttribute<T, ? extends Object>... properties) {
final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(persistentClass);
final Root<T> root = criteriaQuery.from(persistentClass);
criteriaQuery.select(root);
final Object value = values[0];
final SingularAttribute<T, ? extends Object> property = properties[0];
Predicate condition;
condition = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root, value, property);
if (values.length > 1) {
for (int i = 1; i < properties.length; i++) {
final SingularAttribute<T, ? extends Object> property2 = properties[i];
final Object value2 = values[i];
final Predicate condition2 = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root,
value2, property2);
condition = criteriaBuilder.and(condition, condition2);
}
}
criteriaQuery.where(condition);
final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
addCacheHints(typedQuery, "findListByProperty");
return typedQuery.getResultList();
}
@Override
public final List<T> findListByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
final Root<T> root = criteriaQuery.from(getPersistentClass());
criteriaQuery.select(root);
final Predicate condition = criteriaBuilder.equal(root.get(property), value);
criteriaQuery.where(condition);
final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
addCacheHints(typedQuery, "findListByProperty");
return typedQuery.getResultList();
}
@Override
public <V> List<T> findListByEmbeddedProperty(final SingularAttribute<T, V> property, final Class<V> clazz2,
final SingularAttribute<V, ? extends Object> property2, final Object value) {
return findOrderedByPropertyListByEmbeddedProperty(property,clazz2,property2,value,null);
}
@Override
public <V> List<T> findOrderedByPropertyListByEmbeddedProperty(final SingularAttribute<T, V> property,
final Class<V> clazz2, final SingularAttribute<V, ? extends Object> property2, final Object value,
final SingularAttribute<T, ? extends Object> orderByProperty) {
final CriteriaQuery<T> criteriaQuery = criteriaBuilder
.createQuery(persistentClass);
final Root<T> root = criteriaQuery.from(persistentClass);
criteriaQuery.select(root);
if (orderByProperty != null) {
criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
}
final Join<T, V> join = root.join(property);
final Path<? extends Object> path = join.get(property2);
final Predicate condition = criteriaBuilder.equal(path, value);
criteriaQuery.where(condition);
final TypedQuery<T> typedQuery = entityManager
.createQuery(criteriaQuery);
addCacheHints(typedQuery, "findListByEmbeddedProperty." + persistentClass.getSimpleName());
return typedQuery.getResultList();
}
@Override
public final List<T> getAll() {
return getAllOrderBy(null);
}
@Override
public final List<T> getAllOrderBy(final SingularAttribute<T, ? extends Object> orderBy) {
return getPageOrderBy(null, null, orderBy);
}
/**
* Gets the criteria builder.
*
* @return the criteria builder
*/
public final CriteriaBuilder getCriteriaBuilder() {
return criteriaBuilder;
}
/**
* Gets the entity manager.
*
* @return the entity manager
*/
protected final EntityManager getEntityManager() {
return entityManager;
}
/**
* Gets the full text entity manager.
*
* @return the full text entity manager
*/
protected final FullTextEntityManager getFullTextEntityManager() {
return Search.getFullTextEntityManager(getEntityManager());
}
/**
* Gets the metamodel.
*
* @return the metamodel
*/
protected final Metamodel getMetamodel() {
return metamodel;
}
@Override
public final List<T> getPage(int pageNr, int resultPerPage) {
return getPageOrderBy(pageNr, resultPerPage, null);
}
@Override
public final List<T> getPageOrderBy(int pageNr, int resultPerPage, final SingularAttribute<T, ? extends Object> orderBy) {
return getPageOrderBy(Integer.valueOf(pageNr), Integer.valueOf(resultPerPage), orderBy);
}
private List<T> getPageOrderBy(Integer pageNr, Integer resultPerPage,
final SingularAttribute<T, ? extends Object> orderBy) {
final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
final Root<T> root = criteriaQuery.from(getPersistentClass());
criteriaQuery.select(root);
if (orderBy != null) {
criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderBy)));
}
final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
addCacheHints(typedQuery, "getAll");
if (pageNr != null && resultPerPage != null) {
typedQuery.setFirstResult((pageNr - 1) * resultPerPage);
typedQuery.setMaxResults(resultPerPage);
}
return typedQuery.getResultList();
}
/**
* Gets the persistent class.
*
* @return the persistent class
*/
public final Class<T> getPersistentClass() {
return this.persistentClass;
}
@Override
public final Long getSize() {
final CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(countQuery.from(persistentClass)));
return getEntityManager().createQuery(countQuery).getSingleResult();
}
/**
* Inits the.
*/
@PostConstruct
private void init() {
this.criteriaBuilder = getEntityManager().getCriteriaBuilder();
this.metamodel = getEntityManager().getMetamodel();
}
@Override
public final T load(final I id) {
return LoadHelper.recursiveInitialize(getEntityManager().find(getPersistentClass(), id));
}
@Override
public final T merge(final T entity) {
return getEntityManager().merge(entity);
}
@Override
public final void persist(final List<T> list) {
for (final T t : list) {
getEntityManager().persist(t);
}
}
@Override
public final void persist(final T entity) {
getEntityManager().persist(entity);
}
@Override
public final List<T> search(final String searchExpression, final Integer maxResults, final String... fields) {
return getFullTextEntityManager().createFullTextQuery(
getFullTextEntityManager().getSearchFactory().buildQueryBuilder().forEntity(persistentClass).get()
.keyword().wildcard().onFields(fields).matching(searchExpression).createQuery(),
persistentClass).setMaxResults(maxResults).getResultList();
}
}