use of org.apache.ofbiz.entity.GenericModelException in project ofbiz-framework by apache.
the class ModelReader method getEntityCache.
public Map<String, ModelEntity> getEntityCache() throws GenericEntityException {
if (entityCache == null) {
// don't want to block here
synchronized (ModelReader.class) {
// must check if null again as one of the blocked threads can still enter
if (entityCache == null) {
// now it's safe
numEntities = 0;
numViewEntities = 0;
numFields = 0;
numRelations = 0;
numAutoRelations = 0;
entityCache = new HashMap<>();
List<ModelViewEntity> tempViewEntityList = new LinkedList<>();
List<Element> tempExtendEntityElementList = new LinkedList<>();
UtilTimer utilTimer = new UtilTimer();
for (ResourceHandler entityResourceHandler : entityResourceHandlers) {
// utilTimer.timerString("Before getDocument in file " + entityFileName);
Document document = null;
try {
document = entityResourceHandler.getDocument();
} catch (GenericConfigException e) {
throw new GenericEntityConfException("Error getting document from resource handler", e);
}
if (document == null) {
throw new GenericEntityConfException("Could not get document for " + entityResourceHandler.toString());
}
// utilTimer.timerString("Before getDocumentElement in " +
// entityResourceHandler.toString());
Element docElement = document.getDocumentElement();
if (docElement == null) {
return null;
}
docElement.normalize();
Node curChild = docElement.getFirstChild();
ModelInfo def = ModelInfo.createFromElements(ModelInfo.DEFAULT, docElement);
int i = 0;
if (curChild != null) {
utilTimer.timerString("Before start of entity loop in " + entityResourceHandler.toString());
do {
boolean isEntity = "entity".equals(curChild.getNodeName());
boolean isViewEntity = "view-entity".equals(curChild.getNodeName());
boolean isExtendEntity = "extend-entity".equals(curChild.getNodeName());
if ((isEntity || isViewEntity) && curChild.getNodeType() == Node.ELEMENT_NODE) {
i++;
ModelEntity modelEntity = buildEntity(entityResourceHandler, (Element) curChild, i, def);
// put the view entity in a list to get ready for the second pass to populate fields...
if (isViewEntity) {
tempViewEntityList.add((ModelViewEntity) modelEntity);
} else {
entityCache.put(modelEntity.getEntityName(), modelEntity);
}
} else if (isExtendEntity && curChild.getNodeType() == Node.ELEMENT_NODE) {
tempExtendEntityElementList.add((Element) curChild);
}
} while ((curChild = curChild.getNextSibling()) != null);
} else {
Debug.logWarning("No child nodes found.", module);
}
utilTimer.timerString("Finished " + entityResourceHandler.toString() + " - Total Entities: " + i + " FINISHED");
}
// all entity elements in, now go through extend-entity elements and add their stuff
for (Element extendEntityElement : tempExtendEntityElementList) {
String entityName = UtilXml.checkEmpty(extendEntityElement.getAttribute("entity-name"));
ModelEntity modelEntity = entityCache.get(entityName);
if (modelEntity == null)
throw new GenericEntityConfException("Entity to extend does not exist: " + entityName);
modelEntity.addExtendEntity(this, extendEntityElement);
}
// do a pass on all of the view entities now that all of the entities have loaded and populate the fields
while (!tempViewEntityList.isEmpty()) {
int startSize = tempViewEntityList.size();
Iterator<ModelViewEntity> mveIt = tempViewEntityList.iterator();
TEMP_VIEW_LOOP: while (mveIt.hasNext()) {
ModelViewEntity curViewEntity = mveIt.next();
for (ModelViewEntity.ModelMemberEntity mve : curViewEntity.getAllModelMemberEntities()) {
if (!entityCache.containsKey(mve.getEntityName())) {
continue TEMP_VIEW_LOOP;
}
}
mveIt.remove();
curViewEntity.populateFields(this);
for (ModelViewEntity.ModelMemberEntity mve : curViewEntity.getAllModelMemberEntities()) {
ModelEntity me = entityCache.get(mve.getEntityName());
me.addViewEntity(curViewEntity);
}
entityCache.put(curViewEntity.getEntityName(), curViewEntity);
}
if (tempViewEntityList.size() == startSize) {
// that have some reference problem.
break;
}
}
if (!tempViewEntityList.isEmpty()) {
StringBuilder sb = new StringBuilder("View entities reference non-existant members:\n");
Set<String> allViews = new HashSet<>();
for (ModelViewEntity curViewEntity : tempViewEntityList) {
allViews.add(curViewEntity.getEntityName());
}
for (ModelViewEntity curViewEntity : tempViewEntityList) {
Set<String> perViewMissingEntities = new HashSet<>();
Iterator<ModelViewEntity.ModelMemberEntity> mmeIt = curViewEntity.getAllModelMemberEntities().iterator();
while (mmeIt.hasNext()) {
ModelViewEntity.ModelMemberEntity mme = mmeIt.next();
String memberEntityName = mme.getEntityName();
if (!entityCache.containsKey(memberEntityName)) {
// check to see if it is a view
if (!allViews.contains(memberEntityName)) {
// not a view, it's a real missing entity
perViewMissingEntities.add(memberEntityName);
}
}
}
for (String perViewMissingEntity : perViewMissingEntities) {
sb.append("\t[").append(curViewEntity.getEntityName()).append("] missing member entity [").append(perViewMissingEntity).append("]\n");
}
}
throw new GenericEntityConfException(sb.toString());
}
// auto-create relationships
Set<String> orderedMessages = new TreeSet<>();
for (String curEntityName : new TreeSet<>(this.getEntityNames())) {
ModelEntity curModelEntity = this.getModelEntity(curEntityName);
if (curModelEntity instanceof ModelViewEntity) {
// for view-entities auto-create relationships for all member-entity
// relationships that have all corresponding fields in the view-entity
} else {
// for entities auto-create many relationships for all type one relationships
// just in case we add a new relation to the same entity, keep in a separate
// list and add them at the end
List<ModelRelation> newSameEntityRelations = new LinkedList<>();
Iterator<ModelRelation> relationsIter = curModelEntity.getRelationsIterator();
while (relationsIter.hasNext()) {
ModelRelation modelRelation = relationsIter.next();
if (("one".equals(modelRelation.getType()) || "one-nofk".equals(modelRelation.getType())) && !modelRelation.isAutoRelation()) {
ModelEntity relatedEnt = null;
try {
relatedEnt = this.getModelEntity(modelRelation.getRelEntityName());
} catch (GenericModelException e) {
throw new GenericModelException("Error getting related entity [" + modelRelation.getRelEntityName() + "] definition from entity [" + curEntityName + "]", e);
}
// create the new relationship even if one exists so we can show what we are
// looking for in the info message
// don't do relationship to the same entity, unless title is "Parent", then do a
// "Child" automatically
String title = modelRelation.getTitle();
if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName()) && "Parent".equals(title)) {
title = "Child";
}
String description = "";
String type = "";
String relEntityName = curModelEntity.getEntityName();
String fkName = "";
ArrayList<ModelKeyMap> keyMaps = new ArrayList<>();
boolean isAutoRelation = true;
Set<String> curEntityKeyFields = new HashSet<>();
for (ModelKeyMap curkm : modelRelation.getKeyMaps()) {
keyMaps.add(new ModelKeyMap(curkm.getRelFieldName(), curkm.getFieldName()));
curEntityKeyFields.add(curkm.getFieldName());
}
keyMaps.trimToSize();
// the complete pk of the relEntity
if (curModelEntity.containsAllPkFieldNames(curEntityKeyFields)) {
// always use one-nofk, we don't want auto-fks getting in for these automatic ones
type = "one-nofk";
// to keep it clean, remove any additional keys that aren't part of the PK
List<String> curPkFieldNames = curModelEntity.getPkFieldNames();
Iterator<ModelKeyMap> nrkmIter = keyMaps.iterator();
while (nrkmIter.hasNext()) {
ModelKeyMap nrkm = nrkmIter.next();
String checkField = nrkm.getRelFieldName();
if (!curPkFieldNames.contains(checkField)) {
nrkmIter.remove();
}
}
} else {
type = "many";
}
ModelRelation newRel = ModelRelation.create(relatedEnt, description, type, title, relEntityName, fkName, keyMaps, isAutoRelation);
ModelRelation existingRelation = relatedEnt.getRelation(title + curModelEntity.getEntityName());
if (existingRelation == null) {
numAutoRelations++;
if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName())) {
newSameEntityRelations.add(newRel);
} else {
relatedEnt.addRelation(newRel);
}
} else {
if (newRel.equals(existingRelation)) {
// don't warn if the target title+entity = current title+entity
if (Debug.infoOn() && !(title + curModelEntity.getEntityName()).equals(modelRelation.getTitle() + modelRelation.getRelEntityName())) {
// String errorMsg = "Relation already exists to entity [] with title ["
// + targetTitle + "],from entity []";
String message = "Entity [" + relatedEnt.getPackageName() + ":" + relatedEnt.getEntityName() + "] already has identical relationship to entity [" + curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" + newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
orderedMessages.add(message);
}
} else {
String message = "Existing relationship with the same name, but different specs found from what would be auto-created for Entity [" + relatedEnt.getEntityName() + "] and relationship to entity [" + curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" + newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
if (Debug.verboseOn())
Debug.logVerbose(message, module);
}
}
}
}
if (newSameEntityRelations.size() > 0) {
for (ModelRelation newRel : newSameEntityRelations) {
curModelEntity.addRelation(newRel);
}
}
}
}
if (Debug.infoOn()) {
for (String message : orderedMessages) {
Debug.logInfo(message, module);
}
Debug.logInfo("Finished loading entities; #Entities=" + numEntities + " #ViewEntities=" + numViewEntities + " #Fields=" + numFields + " #Relationships=" + numRelations + " #AutoRelationships=" + numAutoRelations, module);
}
}
}
}
return entityCache;
}
use of org.apache.ofbiz.entity.GenericModelException in project ofbiz-framework by apache.
the class GenericDAO method selectListIteratorByCondition.
/* ====================================================================== */
/* ====================================================================== */
/**
* Finds GenericValues by the conditions specified in the EntityCondition object, the the EntityCondition javadoc for more details.
*@param modelEntity The ModelEntity of the Entity as defined in the entity XML file
*@param whereEntityCondition The EntityCondition object that specifies how to constrain this query before any groupings are done (if this is a view entity with group-by aliases)
*@param havingEntityCondition The EntityCondition object that specifies how to constrain this query after any groupings are done (if this is a view entity with group-by aliases)
*@param fieldsToSelect The fields of the named entity to get from the database; if empty or null all fields will be retreived
*@param orderBy The fields of the named entity to order the query by; optionally add a " ASC" for ascending or " DESC" for descending
*@param findOptions An instance of EntityFindOptions that specifies advanced query options. See the EntityFindOptions JavaDoc for more details.
*@return EntityListIterator representing the result of the query: NOTE THAT THIS MUST BE CLOSED WHEN YOU ARE
* DONE WITH IT (preferably in a finally block),
* AND DON'T LEAVE IT OPEN TOO LONG BECAUSE IT WILL MAINTAIN A DATABASE CONNECTION.
*/
public EntityListIterator selectListIteratorByCondition(Delegator delegator, ModelEntity modelEntity, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Collection<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException {
if (modelEntity == null) {
return null;
}
ModelViewEntity modelViewEntity = null;
if (modelEntity instanceof ModelViewEntity) {
modelViewEntity = (ModelViewEntity) modelEntity;
}
// if no find options passed, use default
if (findOptions == null)
findOptions = new EntityFindOptions();
boolean verboseOn = Debug.verboseOn();
if (verboseOn) {
// put this inside an if statement so that we don't have to generate the string when not used...
if (Debug.verboseOn())
Debug.logVerbose("Doing selectListIteratorByCondition with whereEntityCondition: " + whereEntityCondition, module);
}
// make two ArrayLists of fields, one for fields to select and the other for where clause fields (to find by)
List<ModelField> selectFields = new LinkedList<ModelField>();
if (UtilValidate.isNotEmpty(fieldsToSelect)) {
Set<String> tempKeys = new HashSet<String>();
tempKeys.addAll(fieldsToSelect);
Set<String> fieldSetsToInclude = new HashSet<String>();
Set<String> addedFields = new HashSet<String>();
for (String fieldToSelect : fieldsToSelect) {
if (tempKeys.contains(fieldToSelect)) {
ModelField curField = modelEntity.getField(fieldToSelect);
if (curField != null) {
fieldSetsToInclude.add(curField.getFieldSet());
selectFields.add(curField);
tempKeys.remove(fieldToSelect);
addedFields.add(fieldToSelect);
}
}
}
if (tempKeys.size() > 0) {
throw new GenericModelException("In selectListIteratorByCondition invalid field names specified: " + tempKeys.toString());
}
fieldSetsToInclude.remove("");
if (verboseOn) {
Debug.logInfo("[" + modelEntity.getEntityName() + "]: field-sets to include: " + fieldSetsToInclude, module);
}
if (UtilValidate.isNotEmpty(fieldSetsToInclude)) {
Iterator<ModelField> fieldIter = modelEntity.getFieldsIterator();
Set<String> extraFields = new HashSet<String>();
Set<String> reasonSets = new HashSet<String>();
while (fieldIter.hasNext()) {
ModelField curField = fieldIter.next();
String fieldSet = curField.getFieldSet();
if (UtilValidate.isEmpty(fieldSet)) {
continue;
}
if (!fieldSetsToInclude.contains(fieldSet)) {
continue;
}
String fieldName = curField.getName();
if (addedFields.contains(fieldName)) {
continue;
}
reasonSets.add(fieldSet);
extraFields.add(fieldName);
addedFields.add(fieldName);
selectFields.add(curField);
}
if (verboseOn) {
Debug.logInfo("[" + modelEntity.getEntityName() + "]: auto-added select fields: " + extraFields, module);
Debug.logInfo("[" + modelEntity.getEntityName() + "]: auto-added field-sets: " + reasonSets, module);
}
}
} else {
selectFields = modelEntity.getFieldsUnmodifiable();
}
StringBuilder sqlBuffer = new StringBuilder("SELECT ");
if (findOptions.getDistinct()) {
sqlBuffer.append("DISTINCT ");
}
if (selectFields.size() > 0) {
modelEntity.colNameString(selectFields, sqlBuffer, "", ", ", "", datasource.getAliasViewColumns());
} else {
sqlBuffer.append("*");
}
// populate the info from entity-condition in the view-entity, if it is one and there is one
List<EntityCondition> viewWhereConditions = null;
List<EntityCondition> viewHavingConditions = null;
List<String> viewOrderByList = null;
if (modelViewEntity != null) {
viewWhereConditions = new LinkedList<EntityCondition>();
viewHavingConditions = new LinkedList<EntityCondition>();
viewOrderByList = new LinkedList<String>();
modelViewEntity.populateViewEntityConditionInformation(modelFieldTypeReader, viewWhereConditions, viewHavingConditions, viewOrderByList, null);
}
// FROM clause and when necessary the JOIN or LEFT JOIN clause(s) as well
sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, modelFieldTypeReader, datasource));
// WHERE clause
List<EntityConditionParam> whereEntityConditionParams = new LinkedList<EntityConditionParam>();
makeConditionWhereString(sqlBuffer, " WHERE ", modelEntity, whereEntityCondition, viewWhereConditions, whereEntityConditionParams);
// GROUP BY clause for view-entity
if (modelViewEntity != null) {
modelViewEntity.colNameString(modelViewEntity.getGroupBysCopy(selectFields), sqlBuffer, " GROUP BY ", ", ", "", false);
}
// HAVING clause
List<EntityConditionParam> havingEntityConditionParams = new LinkedList<EntityConditionParam>();
makeConditionHavingString(sqlBuffer, " HAVING ", modelEntity, havingEntityCondition, viewHavingConditions, havingEntityConditionParams);
// ORDER BY clause
List<String> orderByExpanded = new LinkedList<String>();
// add the manually specified ones, then the ones in the view entity's entity-condition
if (orderBy != null) {
orderByExpanded.addAll(orderBy);
}
if (viewOrderByList != null) {
// add to end of other order by so that those in method call will override those in view
orderByExpanded.addAll(viewOrderByList);
}
sqlBuffer.append(SqlJdbcUtil.makeOrderByClause(modelEntity, orderByExpanded, datasource));
// OFFSET clause
makeOffsetString(sqlBuffer, findOptions);
// make the final SQL String
String sql = sqlBuffer.toString();
SQLProcessor sqlP = new SQLProcessor(delegator, helperInfo);
sqlP.prepareStatement(sql, findOptions.getSpecifyTypeAndConcur(), findOptions.getResultSetType(), findOptions.getResultSetConcurrency(), findOptions.getFetchSize(), findOptions.getMaxRows());
if (verboseOn) {
// put this inside an if statement so that we don't have to generate the string when not used...
if (Debug.verboseOn())
Debug.logVerbose("Setting the whereEntityConditionParams: " + whereEntityConditionParams, module);
}
// set all of the values from the Where EntityCondition
for (EntityConditionParam whereEntityConditionParam : whereEntityConditionParams) {
SqlJdbcUtil.setValue(sqlP, whereEntityConditionParam.getModelField(), modelEntity.getEntityName(), whereEntityConditionParam.getFieldValue(), modelFieldTypeReader);
}
if (verboseOn) {
// put this inside an if statement so that we don't have to generate the string when not used...
if (Debug.verboseOn())
Debug.logVerbose("Setting the havingEntityConditionParams: " + havingEntityConditionParams, module);
}
// set all of the values from the Having EntityCondition
for (EntityConditionParam havingEntityConditionParam : havingEntityConditionParams) {
SqlJdbcUtil.setValue(sqlP, havingEntityConditionParam.getModelField(), modelEntity.getEntityName(), havingEntityConditionParam.getFieldValue(), modelFieldTypeReader);
}
long queryStartTime = 0;
if (Debug.timingOn()) {
queryStartTime = System.currentTimeMillis();
}
sqlP.executeQuery();
if (Debug.timingOn()) {
long queryEndTime = System.currentTimeMillis();
long queryTotalTime = queryEndTime - queryStartTime;
if (queryTotalTime > 150) {
Debug.logTiming("Ran query in " + queryTotalTime + " milli-seconds: " + " EntityName: " + modelEntity.getEntityName() + " Sql: " + sql + " where clause:" + whereEntityConditionParams, module);
}
}
return new EntityListIterator(sqlP, modelEntity, selectFields, modelFieldTypeReader, this, whereEntityCondition, havingEntityCondition, findOptions.getDistinct());
}
Aggregations