Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.impetus.kundera.query.QueryImpl Maven / Gradle / Ivy
/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
* *
* * 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.impetus.kundera.query;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Parameter;
import javax.persistence.PersistenceException;
import javax.persistence.PostLoad;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.SingularAttribute;
import org.eclipse.persistence.jpa.jpql.parser.AggregateFunction;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.impetus.kundera.Constants;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.EnhanceEntity;
import com.impetus.kundera.index.IndexingConstants;
import com.impetus.kundera.metadata.model.ApplicationMetadata;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.MetamodelImpl;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.metadata.model.type.DefaultEntityType;
import com.impetus.kundera.persistence.EntityManagerFactoryImpl.KunderaMetadata;
import com.impetus.kundera.persistence.EntityReader;
import com.impetus.kundera.persistence.PersistenceDelegator;
import com.impetus.kundera.persistence.context.PersistenceCacheManager;
import com.impetus.kundera.property.PropertyAccessorHelper;
import com.impetus.kundera.query.KunderaQuery.FilterClause;
import com.impetus.kundera.query.KunderaQuery.UpdateClause;
import com.impetus.kundera.utils.KunderaCoreUtils;
import com.impetus.kundera.utils.ReflectUtils;
/**
* The Class QueryImpl.
*
* @author vivek.mishra
* @param
* the element type
*/
public abstract class QueryImpl implements Query, com.impetus.kundera.query.Query
{
/** The kundera query. */
protected KunderaQuery kunderaQuery;
/** The persistence delegeator. */
protected PersistenceDelegator persistenceDelegeator;
/** The kundera metadata. */
protected KunderaMetadata kunderaMetadata;
/** The log. */
private static Logger log = LoggerFactory.getLogger(QueryImpl.class);
/** The parameters. */
private Set> parameters;
/** The hints. */
private Map hints = new HashMap();
/**
* Default maximum result to fetch.
*/
protected int maxResult = 100;
/** The first result. */
protected int firstResult = 0;
/** The fetch size. */
private Integer fetchSize;
/** The is single result. */
protected boolean isSingleResult = false;
/** The ttl. */
protected Integer ttl;
/**
* Instantiates a new query impl.
*
* @param kunderaQuery
* the kundera query
* @param persistenceDelegator
* the persistence delegator
* @param kunderaMetadata
* the kundera metadata
*/
public QueryImpl(KunderaQuery kunderaQuery, PersistenceDelegator persistenceDelegator,
final KunderaMetadata kunderaMetadata)
{
this.kunderaQuery = kunderaQuery;
this.persistenceDelegeator = persistenceDelegator;
this.kunderaMetadata = kunderaMetadata;
}
/**
* Gets the jPA query.
*
* @return the jPA query
*/
public String getJPAQuery()
{
return kunderaQuery.getJPAQuery();
}
/**
* Gets the kundera query.
*
* @return the kunderaQuery
*/
public KunderaQuery getKunderaQuery()
{
return kunderaQuery;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#executeUpdate()
*/
@Override
public int executeUpdate()
{
return onExecuteUpdate();
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getResultList()
*/
@Override
public List> getResultList()
{
if (log.isDebugEnabled())
log.info("On getResultList() executing query: " + getJPAQuery());
// as per JPA post event should happen before fetching data from
// database.
List results = null;
if (getEntityMetadata() == null)
{
// Scalar Query
if (kunderaQuery.isDeleteUpdate())
{
executeUpdate();
}
else
{
Client client = persistenceDelegeator.getClient(kunderaQuery.getPersistenceUnit());
results = populateEntities(null, client);
}
}
else
{
handlePostEvent();
if (kunderaQuery.isDeleteUpdate())
{
executeUpdate();
}
else
{
results = fetch();
assignReferenceToProxy(results);
}
}
return results != null ? results : new ArrayList();
}
/**
* Sets the relation entities.
*
* @param enhanceEntities
* the enhance entities
* @param client
* the client
* @param m
* the m
* @return the list
*/
protected List setRelationEntities(List enhanceEntities, Client client, EntityMetadata m)
{
// Enhance entities can contain or may not contain relation.
// if it contain a relation means it is a child
// if it does not then it means it is a parent.
List result = new ArrayList();
// Stack of objects. To be used for referring any similar object found
// later.
// This prevents infinite recursive loop and hence prevents stack
// overflow.
Map relationStack = new HashMap();
if (enhanceEntities != null)
{
for (Object e : enhanceEntities)
{
addToRelationStack(relationStack, e, m);
}
}
if (enhanceEntities != null)
{
for (Object e : enhanceEntities)
{
if (!(e instanceof EnhanceEntity))
{
e = new EnhanceEntity(e, PropertyAccessorHelper.getId(e, m), null);
}
EnhanceEntity ee = (EnhanceEntity) e;
result.add(getReader().recursivelyFindEntities(ee.getEntity(), ee.getRelations(), m,
persistenceDelegeator, false, relationStack));
}
}
return result;
}
// Adds an object to the stack for referring
/**
* Adds the to relation stack.
*
* @param relationStack
* the relation stack
* @param entity
* the entity
* @param m
* the m
*/
protected void addToRelationStack(Map relationStack, Object entity, EntityMetadata m)
{
Object obj = entity;
if (entity instanceof EnhanceEntity)
{
obj = ((EnhanceEntity) entity).getEntity();
}
relationStack.put(obj.getClass().getCanonicalName() + "#" + PropertyAccessorHelper.getId(obj, m), obj);
}
/**
* Populate using lucene for embeddeId.
*
* @param m
* the m
* @param client
* the client
* @param result
* the result
* @param searchFilter
* the search filter
* @param metaModel
* the meta model
* @return the list
*/
private List populateEmbeddedIdUsingLucene(EntityMetadata m, Client client, List result,
Map searchFilter, MetamodelImpl metaModel)
{
List compositeIds = new ArrayList();
for (String compositeIdName : searchFilter.keySet())
{
Object compositeId = null;
Map uniquePKs = (Map) searchFilter.get(compositeIdName);
compositeId = KunderaCoreUtils.initialize(m.getIdAttribute().getBindableJavaType(), compositeId);
prepareCompositeIdObject(m.getIdAttribute(), compositeId, uniquePKs, metaModel);
compositeIds.add(compositeId);
}
return findUsingLucene(m, client, compositeIds.toArray());
}
/**
* Prepare composite id object.
*
* @param attribute
* the attribute
* @param compositeId
* the composite id
* @param uniquePKs
* the unique p ks
* @param metaModel
* the meta model
* @return the object
*/
private Object prepareCompositeIdObject(final SingularAttribute attribute, Object compositeId,
Map uniquePKs, MetamodelImpl metaModel)
{
Field[] fields = attribute.getBindableJavaType().getDeclaredFields();
EmbeddableType embeddable = metaModel.embeddable(attribute.getBindableJavaType());
for (Field field : attribute.getBindableJavaType().getDeclaredFields())
{
if (!ReflectUtils.isTransientOrStatic(field))
{
if (metaModel.isEmbeddable(((AbstractAttribute) embeddable.getAttribute(field.getName()))
.getBindableJavaType()))
{
try
{
field.setAccessible(true);
Object embeddedObject = prepareCompositeIdObject(
(SingularAttribute) embeddable.getAttribute(field.getName()),
KunderaCoreUtils.initialize(((AbstractAttribute) embeddable.getAttribute(field
.getName())).getBindableJavaType(), field.get(compositeId)), uniquePKs,
metaModel);
PropertyAccessorHelper.set(compositeId, field, embeddedObject);
}
catch (IllegalAccessException e)
{
log.error(e.getMessage());
}
}
else
{
PropertyAccessorHelper.set(
compositeId,
field,
PropertyAccessorHelper.fromSourceToTargetClass(field.getType(), String.class,
uniquePKs.get(field.getName())));
}
}
}
return compositeId;
}
/**
* find data using lucene.
*
* @param m
* the m
* @param client
* the client
* @param primaryKeys
* the primary keys
* @return the list
*/
private List findUsingLucene(EntityMetadata m, Client client, Object[] primaryKeys)
{
String idField = m.getIdAttribute().getName();
String equals = "=";
MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
m.getPersistenceUnit());
EntityType entityType = metaModel.entity(m.getEntityClazz());
String columnName = ((AbstractAttribute) entityType.getAttribute(idField)).getJPAColumnName();
List result = new ArrayList();
Queue queue = getKunderaQuery().getFilterClauseQueue();
KunderaQuery kunderaQuery = getKunderaQuery();
for (Object primaryKey : primaryKeys)
{
FilterClause filterClause = kunderaQuery.new FilterClause(columnName, equals, primaryKey, idField);
kunderaQuery.setFilter(kunderaQuery.getEntityAlias() + "." + columnName + " = " + primaryKey);
queue.clear();
queue.add(filterClause);
List object = findUsingLucene(m, client);
if (object != null && !object.isEmpty())
result.add(object.get(0));
}
return result;
}
/**
* Populate using lucene.
*
* @param m
* the m
* @param client
* the client
* @param result
* the result
* @param columnsToSelect
* List of column names to be selected (rest should be ignored)
* @return the list
*/
protected List populateUsingLucene(EntityMetadata m, Client client, List result,
String[] columnsToSelect)
{
Set uniquePKs = null;
MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
m.getPersistenceUnit());
if (client.getIndexManager().getIndexer().getClass().getName().equals(IndexingConstants.LUCENE_INDEXER))
{
String luceneQ = KunderaCoreUtils.getLuceneQueryFromJPAQuery(kunderaQuery, kunderaMetadata);
Map searchFilter = client.getIndexManager().search(m.getEntityClazz(), luceneQ,
Constants.INVALID, Constants.INVALID);
// Map searchFilter =
// client.getIndexManager().search(kunderaMetadata, kunderaQuery,
// persistenceDelegeator, m);
boolean isEmbeddedId = metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType());
if (isEmbeddedId)
{
return populateEmbeddedIdUsingLucene(m, client, result, searchFilter, metaModel);
}
Object[] primaryKeys = searchFilter.values().toArray(new Object[] {});
// Object[] primaryKeys =
// ((List)searchFilter.get("primaryKeys")).toArray(new Object[] {});
uniquePKs = new HashSet(Arrays.asList(primaryKeys));
return findUsingLucene(m, client, uniquePKs.toArray());
}
else
{
return populateUsingElasticSearch(client, m);
}
}
/**
* Populate using elastic search.
*
* @param client
* the client
* @param EntityMetadata
* the m
* @return Result list by fetching from ES
*/
private List populateUsingElasticSearch(Client client, EntityMetadata m)
{
Map searchFilter = client.getIndexManager().search(kunderaMetadata, kunderaQuery,
persistenceDelegeator, m, this.maxResult);
Object[] primaryKeys = ((Map) searchFilter.get(Constants.PRIMARY_KEYS)).values().toArray(
new Object[] {});
Map aggregations = (Map) searchFilter.get(Constants.AGGREGATIONS);
Iterable resultOrderIterable = (Iterable) searchFilter
.get(Constants.SELECT_EXPRESSION_ORDER);
List results = new ArrayList();
if (!kunderaQuery.isAggregated())
{
results.addAll(findUsingLucene(m, client, primaryKeys));
}
else
{
if (KunderaQueryUtils.hasGroupBy(kunderaQuery.getJpqlExpression()))
{
populateGroupByResponse(aggregations, resultOrderIterable, results, client, m);
}
else
{
Iterator resultOrder = resultOrderIterable.iterator();
while (resultOrder.hasNext())
{
Expression expression = (Expression) resultOrder.next();
if (AggregateFunction.class.isAssignableFrom(expression.getClass()))
{
if (aggregations.get(expression.toParsedText()) != null)
{
results.add(aggregations.get(expression.toParsedText()));
}
}
else
{
results.addAll(findUsingLucene(m, client, new Object[] { primaryKeys[0] }));
}
}
}
}
return results;
}
/**
* Populate group by response.
*
* @param aggregations
* the aggregations
* @param resultOrderIterable
* the result order iterable
* @param results
* the results
* @param client
* the client
* @param m
* the m
*/
private void populateGroupByResponse(Map aggregations, Iterable resultOrderIterable,
List results, Client client, EntityMetadata m)
{
List temp;
Object entity = null;
for (String entry : aggregations.keySet())
{
entity = null;
Object obj = aggregations.get(entry);
temp = new ArrayList<>();
Iterator resultOrder = resultOrderIterable.iterator();
while (resultOrder.hasNext())
{
Expression expression = (Expression) resultOrder.next();
if (AggregateFunction.class.isAssignableFrom(expression.getClass()))
{
if (((Map) obj).get(expression.toParsedText()) != null)
{
temp.add(((Map) obj).get(expression.toParsedText()));
}
}
else
{
if (entity == null)
{
entity = findUsingLucene(m, client, new Object[] { entry }).get(0);
}
temp.add(getEntityFieldValue(m, entity, expression.toParsedText()));
}
}
results.add(temp.size() == 1 ? temp.get(0) : temp);
}
}
/**
* Gets the entity field value.
*
* @param entityMetadata
* the entity metadata
* @param entity
* the entity
* @param field
* the field
* @return the entity field value
*/
private Object getEntityFieldValue(EntityMetadata entityMetadata, Object entity, String field)
{
Class clazz = entityMetadata.getEntityClazz();
MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
entityMetadata.getPersistenceUnit());
EntityType entityType = metaModel.entity(clazz);
if (field.indexOf(".") > 0 && entityMetadata.getEntityClazz().equals(entity.getClass()))
{
String fieldName = field.substring(field.indexOf(".") + 1, field.length());
Attribute attribute = entityType.getAttribute(fieldName);
return PropertyAccessorHelper.getObject(entity, (Field) attribute.getJavaMember());
}
else
{
// for hbase v2 client (sends arraylist for specific fields)
if (entity instanceof ArrayList)
{
Object element = ((ArrayList) entity).get(0);
((ArrayList) entity).remove(0);
return element;
}
else
{
return entity;
}
}
}
/**
* Populate entities, Method to populate data in case no relation exist!.
*
* @param m
* the m
* @param client
* the client
* @return the list
*/
protected abstract List populateEntities(EntityMetadata m, Client client);
/**
* Find using lucene.
*
* @param m
* the m
* @param client
* the client
* @return the list
*/
protected abstract List findUsingLucene(EntityMetadata m, Client client);
/**
* Recursively populate entities.
*
* @param m
* the m
* @param client
* the client
* @return the list
*/
protected abstract List recursivelyPopulateEntities(EntityMetadata m, Client client);
/**
* Method returns entity reader.
*
* @return entityReader entity reader.
*/
protected abstract EntityReader getReader();
/**
* Method to be invoked on query.executeUpdate().
*
* @return the int
*/
protected abstract int onExecuteUpdate();
/**
* Returns entity metadata, in case of native query mapped class is present
* within application metadata.
*
* @return entityMetadata entity metadata.
*/
protected EntityMetadata getEntityMetadata()
{
return kunderaQuery.getEntityMetadata();
}
/**
* On update delete event.
*
* @return the int
*/
protected int onUpdateDeleteEvent()
{
if (kunderaQuery.isDeleteUpdate())
{
List result = fetch();
onDeleteOrUpdate(result);
return result != null ? result.size() : 0;
}
return 0;
}
/**
* Performs delete or update based on query.
*
* @param results
* list of objects to be merged/deleted.
*/
protected void onDeleteOrUpdate(List results)
{
if (results != null)
{
if (!kunderaQuery.isUpdateClause())
{
// then case of delete
for (Object result : results)
{
PersistenceCacheManager.addEntityToPersistenceCache(result, persistenceDelegeator,
PropertyAccessorHelper.getId(result, this.getEntityMetadata()));
persistenceDelegeator.remove(result);
}
}
else
{
EntityMetadata entityMetadata = getEntityMetadata();
for (Object result : results)
{
PersistenceCacheManager.addEntityToPersistenceCache(result, persistenceDelegeator,
PropertyAccessorHelper.getId(result, this.getEntityMetadata()));
for (UpdateClause c : kunderaQuery.getUpdateClauseQueue())
{
String columnName = c.getProperty();
try
{
DefaultEntityType entityType = (DefaultEntityType) kunderaMetadata.getApplicationMetadata()
.getMetamodel(entityMetadata.getPersistenceUnit())
.entity(entityMetadata.getEntityClazz());
// That will always be attribute name.
Attribute attribute = entityType.getAttribute(columnName);
// TODO : catch column name.
if (c.getValue() instanceof String)
{
PropertyAccessorHelper.set(result, (Field) attribute.getJavaMember(), c.getValue()
.toString());
}
else
{
PropertyAccessorHelper.set(result, (Field) attribute.getJavaMember(), c.getValue());
}
persistenceDelegeator.merge(result);
}
catch (IllegalArgumentException iax)
{
log.error("Invalid column name: " + columnName + " for class : "
+ entityMetadata.getEntityClazz());
throw new QueryHandlerException("Error while executing query: " + iax);
}
}
}
}
}
}
/**
* *********************** Methods from {@link Query} interface
* ******************************.
*
* @return the single result
*/
/* @see javax.persistence.Query#getSingleResult() */
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getSingleResult()
*/
@Override
public Object getSingleResult()
{
// to fetch a single result form database.
isSingleResult = true;
List results = getResultList();
isSingleResult = false;
return onReturnResults(results);
}
/* @see javax.persistence.Query#setFirstResult(int) */
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setFirstResult(int)
*/
@Override
public Query setFirstResult(int startPosition)
{
this.firstResult = startPosition;
return this;
}
/*
* @see
* javax.persistence.Query#setFlushMode(javax.persistence.FlushModeType)
*/
/*
* (non-Javadoc)
*
* @see
* javax.persistence.Query#setFlushMode(javax.persistence.FlushModeType)
*/
@Override
public Query setFlushMode(FlushModeType flushMode)
{
throw new UnsupportedOperationException("setFlushMode is unsupported by Kundera");
}
/**
* Sets hint name and value into hints map and returns instance of
* {@link Query}.
*
* @param hintName
* the hint name
* @param value
* the value
* @return the query
*/
@Override
public Query setHint(String hintName, Object value)
{
hints.put(hintName, value);
return this;
}
/* @see javax.persistence.Query#setMaxResults(int) */
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setMaxResults(int)
*/
@Override
public Query setMaxResults(int maxResult)
{
this.maxResult = maxResult;
return this;
}
/*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.lang.Object)
*/
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.lang.Object)
*/
@Override
public Query setParameter(String name, Object value)
{
kunderaQuery.setParameter(name, value);
return this;
}
/* @see javax.persistence.Query#setParameter(int, java.lang.Object) */
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(int, java.lang.Object)
*/
@Override
public Query setParameter(int position, Object value)
{
kunderaQuery.setParameter(position, value);
return this;
}
/*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.util.Date, javax.persistence.TemporalType)
*/
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.util.Date, javax.persistence.TemporalType)
*/
@Override
public Query setParameter(String name, Date value, TemporalType temporalType)
{
// Purpose of temporal type is to set value based on temporal type.
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.util.Calendar, javax.persistence.TemporalType)
*/
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(java.lang.String,
* java.util.Calendar, javax.persistence.TemporalType)
*/
@Override
public Query setParameter(String name, Calendar value, TemporalType temporalType)
{
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* @see javax.persistence.Query#setParameter(int, java.util.Date,
* javax.persistence.TemporalType)
*/
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(int, java.util.Date,
* javax.persistence.TemporalType)
*/
@Override
public Query setParameter(int position, Date value, TemporalType temporalType)
{
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* @see javax.persistence.Query#setParameter(int, java.util.Calendar,
* javax.persistence.TemporalType)
*/
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(int, java.util.Calendar,
* javax.persistence.TemporalType)
*/
@Override
public Query setParameter(int position, Calendar value, TemporalType temporalType)
{
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getMaxResults()
*/
@Override
public int getMaxResults()
{
return maxResult;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getFirstResult()
*/
@Override
public int getFirstResult()
{
throw new UnsupportedOperationException("getFirstResult is unsupported by Kundera");
}
/**
* Returns a {@link Map} containing query hints set by user.
*
* @return the hints
*/
@Override
public Map getHints()
{
return hints;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(javax.persistence.Parameter,
* java.lang.Object)
*/
@Override
public Query setParameter(Parameter paramParameter, T paramT)
{
if (!getParameters().contains(paramParameter))
{
throw new IllegalArgumentException("parameter does not correspond to a parameter of the query");
}
if (paramParameter.getName() != null)
{
kunderaQuery.setParameter(paramParameter.getName(), paramT);
}
else
{
kunderaQuery.setParameter(paramParameter.getPosition(), paramT);
}
return this;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(javax.persistence.Parameter,
* java.util.Calendar, javax.persistence.TemporalType)
*/
@Override
public Query setParameter(Parameter paramParameter, Calendar paramCalendar, TemporalType paramTemporalType)
{
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setParameter(javax.persistence.Parameter,
* java.util.Date, javax.persistence.TemporalType)
*/
@Override
public Query setParameter(Parameter paramParameter, Date paramDate, TemporalType paramTemporalType)
{
throw new UnsupportedOperationException("setParameter is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameters()
*/
@Override
public Set> getParameters()
{
if (parameters == null)
{
parameters = kunderaQuery.getParameters();
if (parameters == null)
{
parameters = new HashSet>();
}
}
return parameters;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameter(java.lang.String)
*/
@Override
public Parameter> getParameter(String paramString)
{
onNativeCondition();
getParameters();
return getParameterByName(paramString);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameter(java.lang.String,
* java.lang.Class)
*/
@Override
public Parameter getParameter(String paramString, Class paramClass)
{
onNativeCondition();
Parameter parameter = getParameterByName(paramString);
return onTypeCheck(paramClass, parameter);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameter(int)
*/
@Override
public Parameter> getParameter(int paramInt)
{
onNativeCondition();
getParameters();
return getParameterByOrdinal(paramInt);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameter(int, java.lang.Class)
*/
@Override
public Parameter getParameter(int paramInt, Class paramClass)
{
onNativeCondition();
getParameters();
Parameter parameter = getParameterByOrdinal(paramInt);
return onTypeCheck(paramClass, parameter);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#isBound(javax.persistence.Parameter)
*/
@Override
public boolean isBound(Parameter> paramParameter)
{
return kunderaQuery.isBound(paramParameter);
}
/*
* (non-Javadoc)
*
* @see
* javax.persistence.Query#getParameterValue(javax.persistence.Parameter)
*/
@Override
public T getParameterValue(Parameter paramParameter)
{
Object value = kunderaQuery.getClauseValue(paramParameter);
if (value == null)
{
throw new IllegalStateException("parameter has not been bound" + paramParameter);
}
return (T) value;
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameterValue(java.lang.String)
*/
@Override
public Object getParameterValue(String paramString)
{
return onParameterValue(":" + paramString);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getParameterValue(int)
*/
@Override
public Object getParameterValue(int paramInt)
{
return onParameterValue("?" + paramInt);
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getFlushMode()
*/
@Override
public FlushModeType getFlushMode()
{
throw new UnsupportedOperationException("getFlushMode is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#setLockMode(javax.persistence.LockModeType)
*/
@Override
public Query setLockMode(LockModeType paramLockModeType)
{
throw new UnsupportedOperationException("setLockMode is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#getLockMode()
*/
@Override
public LockModeType getLockMode()
{
throw new UnsupportedOperationException("getLockMode is unsupported by Kundera");
}
/*
* (non-Javadoc)
*
* @see javax.persistence.Query#unwrap(java.lang.Class)
*/
@Override
public T unwrap(Class paramClass)
{
try
{
return (T) this;
}
catch (ClassCastException ccex)
{
throw new PersistenceException("Provider does not support the call for class type:[" + paramClass + "]");
}
}
/**
* Returns specific parameter instance for given name.
*
* @param name
* parameter name.
* @return parameter
*/
private Parameter getParameterByName(String name)
{
if (getParameters() != null)
{
for (Parameter p : parameters)
{
if (name.equals(p.getName()))
{
return p;
}
}
}
return null;
}
/**
* Returns parameter by ordinal.
*
* @param position
* position
* @return parameter instance.
*/
private Parameter getParameterByOrdinal(Integer position)
{
for (Parameter p : parameters)
{
if (position.equals(p.getPosition()))
{
return p;
}
}
return null;
}
/**
* Method to handle get/set Parameter supplied for native query.
*/
private void onNativeCondition()
{
ApplicationMetadata appMetadata = kunderaMetadata.getApplicationMetadata();
if (appMetadata.isNative(getJPAQuery()))
{
throw new IllegalStateException(
"invoked on a native query when the implementation does not support this use");
}
}
/**
* Validated parameter's class with input paramClass. Returns back parameter
* if it matches, else throws an {@link IllegalArgumentException}.
*
* @param
* type of class.
* @param paramClass
* expected class type.
* @param parameter
* parameter
* @return parameter if it matches, else throws an
* {@link IllegalArgumentException}.
*/
private Parameter onTypeCheck(Class paramClass, Parameter parameter)
{
if (parameter != null && parameter.getParameterType() != null
&& parameter.getParameterType().equals(paramClass))
{
return parameter;
}
throw new IllegalArgumentException(
"The parameter of the specified name does not exist or is not assignable to the type");
}
/**
* Returns parameter value.
*
* @param paramString
* parameter as string.
*
* @return value of parameter.
*/
private List onParameterValue(String paramString)
{
List value = kunderaQuery.getClauseValue(paramString);
if (value == null)
{
throw new IllegalStateException("parameter has not been bound" + paramString);
}
return value;
}
/**
* Gets the columns.
*
* @param columns
* the columns
* @param m
* the m
* @return the columns
*/
protected String[] getColumns(final String[] columns, final EntityMetadata m)
{
List columnAsList = new ArrayList();
if (columns != null && columns.length > 0)
{
MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
m.getPersistenceUnit());
EntityType entity = metaModel.entity(m.getEntityClazz());
for (int i = 1; i < columns.length; i++)
{
if (columns[i] != null)
{
Attribute col = entity.getAttribute(columns[i]);
if (col == null)
{
throw new QueryHandlerException("column type is null for: " + columns);
}
columnAsList.add(((AbstractAttribute) col).getJPAColumnName());
}
}
}
return columnAsList.toArray(new String[] {});
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.query.Query#setFetchSize(java.lang.Integer)
*/
public void setFetchSize(Integer fetchsize)
{
this.fetchSize = fetchsize;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.query.Query#getFetchSize()
*/
public Integer getFetchSize()
{
return this.fetchSize;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.query.Query#applyTTL(int)
*/
public void applyTTL(int ttlInSeconds)
{
this.ttl = ttlInSeconds;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.query.Query#close()
*/
public abstract void close();
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.query.Query#iterate()
*/
public abstract Iterator iterate();
/**
* Handle post event callbacks.
*
*/
protected void handlePostEvent()
{
EntityMetadata metadata = getEntityMetadata();
if (!kunderaQuery.isDeleteUpdate())
{
persistenceDelegeator.getEventDispatcher().fireEventListeners(metadata, null, PostLoad.class);
}
}
/**
* Returns collection of fetched entities.
*
* @return the list
*/
protected List fetch()
{
EntityMetadata metadata = getEntityMetadata();
Client client = persistenceDelegeator.getClient(metadata);
List results = isRelational(metadata) && !kunderaQuery.isNative() ? recursivelyPopulateEntities(metadata,
client) : populateEntities(metadata, client);
return results;
}
/**
* On validate single result.
*
* @param results
* the results
*/
protected void onValidateSingleResult(List results)
{
if (results == null || results.isEmpty())
{
log.error("No result found for {} ", kunderaQuery.getJPAQuery());
throw new NoResultException("No result found!");
}
if (results.size() > 1)
{
log.error("Non unique results found for query {} ", kunderaQuery.getJPAQuery());
throw new NonUniqueResultException("Containing more than one result!");
}
}
/**
* On return results.
*
* @param results
* the results
* @return the object
*/
protected Object onReturnResults(List results)
{
onValidateSingleResult(results);
return results.get(0);
}
/**
* Returns true, if associated entity holds relational references(e.g. @OneToMany
* etc.) else false.
*
* @param m
* entity metadata
*
* @return true, if holds relation else false
*/
private boolean isRelational(EntityMetadata m)
{
// if related via join table OR contains relations.
return m.isRelationViaJoinTable() || (m.getRelationNames() != null && (!m.getRelationNames().isEmpty()));
}
/**
* If returned collection of object holds a reference to.
*
* @param results
* the results
*/
private void assignReferenceToProxy(List results)
{
if (results != null)
{
for (Object obj : results)
{
kunderaMetadata.getCoreMetadata().getLazyInitializerFactory().setProxyOwners(getEntityMetadata(), obj);
}
}
}
}