package io.robe.hibernate.criteria.hql; import io.robe.common.dto.BooleanHolder; import io.robe.common.dto.Pair; import io.robe.hibernate.criteria.api.Criteria; import io.robe.hibernate.criteria.api.Result; import io.robe.hibernate.criteria.api.Transformer; import io.robe.hibernate.criteria.api.cache.EntityMetaFinder; import io.robe.hibernate.criteria.api.cache.FieldMeta; import io.robe.hibernate.criteria.hql.transformers.AliasToBeanResultTransformer; import io.robe.hibernate.criteria.hql.transformers.AliasToEntityMapResultTransformer; import org.hibernate.Query; import org.hibernate.Session; import java.util.*; /** * Created by kamilbukum on 10/01/2017. */ public class TransformerImpl<E> extends Transformer<E> { private static EntityMetaFinder finder = new EntityMetaFinderImpl(); private Session session; public TransformerImpl(Session session) { this(session, null); } public TransformerImpl(Session session, Class<? extends E> transformClass) { super(transformClass, finder); this.session = session; } @Override public List<E> list(Criteria<E> criteria) { TransformerUtil.Elements elements = new TransformerUtil.Elements(); Pair<String, Map<String, Object>> pair = TransformerUtil.query(criteria, elements); Query query = session.createQuery(pair.getLeft()); if(criteria.getLimit() != null) { query.setMaxResults(criteria.getLimit()); } if(criteria.getOffset() != null) { query.setFirstResult(criteria.getOffset()); } for(Map.Entry<String, Object> parameter: pair.getRight().entrySet()) { setParameter(query, parameter.getKey(), parameter.getValue()); } setResultTransformer(query); List<E> destinationList = query.list(); setElementsToList(criteria, pair.getRight(), elements, destinationList); return destinationList; } public void setElementsToList(Criteria<E> criteria, Map<String, Object> variableMap, TransformerUtil.Elements elements, List<?> destinationList) { if(elements.elementsQuery == null || elements.elementsMap == null || elements.elementsMap.size() == 0) return; Query elementsQuery = session.createQuery(elements.elementsQuery); if(criteria.getLimit() != null) { elementsQuery.setMaxResults(criteria.getLimit()); } if(criteria.getOffset() != null) { elementsQuery.setFirstResult(criteria.getOffset()); } for(Map.Entry<String, Object> parameter: variableMap.entrySet()) { setParameter(elementsQuery, parameter.getKey(), parameter.getValue()); } List<?> sourceList = elementsQuery.list(); if(sourceList.size() > 0) { for(int i = 0 ; i < destinationList.size(); i++) { Object sourceObject = sourceList.get(i); Object destinationObject = destinationList.get(i); for(Map.Entry<String, String> elementEntry: elements.elementsMap.entrySet()) { FieldMeta srcField = criteria.getMeta().getFieldMap().get(elementEntry.getKey()); FieldMeta destinationField = criteria.getTransformer().getMeta().getFieldMap().get(elementEntry.getKey()); try { if(!destinationField.getField().isAccessible()) { destinationField.getField().setAccessible(true); } if(!srcField.getField().isAccessible()) { srcField.getField().setAccessible(true); } destinationField.getField().set(destinationObject, srcField.getField().get(sourceObject)); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } @Override public Result<E> pairList(Criteria<E> criteria) { Result<E> result = new Result<>(); BooleanHolder groupBy = new BooleanHolder(false); TransformerUtil.Elements elements = new TransformerUtil.Elements(); Pair<String, Pair<String, Map<String, Object>>> pair = TransformerUtil.pairList(criteria, elements, groupBy); Query listQuery = session.createQuery(pair.getLeft()); if(elements.elementsMap != null && elements.elementsMap.size() > 0) { } if(criteria.getLimit() != null) { listQuery.setMaxResults(criteria.getLimit()); } if(criteria.getOffset() != null) { listQuery.setFirstResult(criteria.getOffset()); } setResultTransformer(listQuery); Query countQuery = session.createQuery(pair.getRight().getLeft()); for(Map.Entry<String, Object> parameter: pair.getRight().getRight().entrySet()) { setParameter(listQuery, parameter.getKey(), parameter.getValue()); setParameter(countQuery, parameter.getKey(), parameter.getValue()); } List<E> destinationList = listQuery.list(); setElementsToList(criteria, pair.getRight().getRight(), elements, destinationList); result.setList(destinationList); result.setTotalCount(groupBy.is() ? countQuery.list().size(): (long)countQuery.uniqueResult()); return result; } public void setParameter(Query query, String key, Object value) { if(value instanceof Collection) { query.setParameterList(key, (Collection) value); } else { query.setParameter(key, value); } } @Override public Long count(Criteria<E> criteria) { BooleanHolder groupBy = new BooleanHolder(false); Pair<String, Map<String, Object>> pair = TransformerUtil.count(criteria, groupBy); Query query = session.createQuery(pair.getLeft()); for(Map.Entry<String, Object> parameter: pair.getRight().entrySet()) { setParameter(query, parameter.getKey(), parameter.getValue()); } setResultTransformer(query); return groupBy.is() ? query.list().size(): (long)query.uniqueResult(); } @Override public Object uniqueResult(Criteria<E> criteria) { TransformerUtil.Elements elements = new TransformerUtil.Elements(); Pair<String, Map<String, Object>> pair = TransformerUtil.query(criteria, elements); Query query = session.createQuery(pair.getLeft()); for(Map.Entry<String, Object> parameter: pair.getRight().entrySet()) { setParameter(query, parameter.getKey(), parameter.getValue()); } setResultTransformer(query); return query.uniqueResult(); } @Override public EntityMetaFinder getFinder() { return finder; } private void setResultTransformer(Query query){ switch (this.getTransformType()) { case MAP: query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE); break; case DTO: query.setResultTransformer(new AliasToBeanResultTransformer(this.getTransformClass(), this.getMeta())); break; } } }