Search in sources :

Example 6 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class GenericDAO method selectCountByCondition.

public long selectCountByCondition(Delegator delegator, ModelEntity modelEntity, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, List<ModelField> selectFields, EntityFindOptions findOptions) throws GenericEntityException {
    if (modelEntity == null) {
        return 0;
    }
    // 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);
    }
    boolean isGroupBy = false;
    ModelViewEntity modelViewEntity = null;
    if (modelEntity instanceof ModelViewEntity) {
        modelViewEntity = (ModelViewEntity) modelEntity;
        isGroupBy = modelViewEntity.getGroupBysSize() > 0;
    }
    // To get a count of the rows that will be returned when there is a GROUP BY, must do something like:
    // SELECT COUNT(1) FROM (SELECT COUNT(1) FROM OFBIZ.POSTAL_ADDRESS PA GROUP BY PA.CITY) TEMP_NAME
    // instead of a simple:
    // SELECT COUNT(1) FROM OFBIZ.POSTAL_ADDRESS PA GROUP BY PA.CITY
    StringBuilder sqlBuffer = new StringBuilder("SELECT ");
    if (isGroupBy) {
        sqlBuffer.append("COUNT(1) FROM (SELECT ");
    }
    if (findOptions.getDistinct()) {
        /* DEJ20100304: the code below was causing problems so the line above may be used instead, but hopefully this is fixed now 
             * may need varying SQL for different databases, and also in view-entities in some cases it seems to 
             * cause the "COUNT(DISTINCT " to appear twice, causing an attempt to try to count a count (function="count-distinct", distinct=true in find options)
             */
        if (selectFields != null && selectFields.size() > 0) {
            ModelField firstSelectField = selectFields.get(0);
            ModelViewEntity.ModelAlias firstModelAlias = modelViewEntity != null ? modelViewEntity.getAlias(firstSelectField.getName()) : null;
            if (firstModelAlias != null && UtilValidate.isNotEmpty(firstModelAlias.getFunction())) {
                // if the field has a function already we don't want to count just it, would be meaningless
                sqlBuffer.append("COUNT(DISTINCT *) ");
            } else {
                sqlBuffer.append("COUNT(DISTINCT ");
                // this only seems to support a single column, which is not desirable but seems a lot better than no columns or in certain cases all columns
                sqlBuffer.append(firstSelectField.getColValue());
                // sqlBuffer.append(modelEntity.colNameString(selectFields, ", ", "", datasource.aliasViews));
                sqlBuffer.append(")");
            }
        } else {
            sqlBuffer.append("COUNT(DISTINCT *) ");
        }
    } else {
        // NOTE DEJ20080701 Changed from COUNT(*) to COUNT(1) to improve performance, and should get the same results at least when there is no DISTINCT
        sqlBuffer.append("COUNT(1) ");
    }
    // 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 (isGroupBy) {
        modelViewEntity.colNameString(modelViewEntity.getGroupBysCopy(), sqlBuffer, " GROUP BY ", ", ", "", false);
    }
    // HAVING clause
    List<EntityConditionParam> havingEntityConditionParams = new LinkedList<EntityConditionParam>();
    makeConditionHavingString(sqlBuffer, " HAVING ", modelEntity, havingEntityCondition, viewHavingConditions, havingEntityConditionParams);
    if (isGroupBy) {
        sqlBuffer.append(") TEMP_NAME");
    }
    String sql = sqlBuffer.toString();
    if (Debug.verboseOn())
        Debug.logVerbose("Count select sql: " + sql, module);
    try (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);
        }
        try {
            sqlP.executeQuery();
            long count = 0;
            ResultSet resultSet = sqlP.getResultSet();
            if (resultSet.next()) {
                count = resultSet.getLong(1);
            }
            return count;
        } catch (SQLException e) {
            throw new GenericDataSourceException("Error getting count value", e);
        }
    }
}
Also used : SQLException(java.sql.SQLException) EntityCondition(org.apache.ofbiz.entity.condition.EntityCondition) LinkedList(java.util.LinkedList) SQLProcessor(org.apache.ofbiz.entity.jdbc.SQLProcessor) ModelField(org.apache.ofbiz.entity.model.ModelField) EntityFindOptions(org.apache.ofbiz.entity.util.EntityFindOptions) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ResultSet(java.sql.ResultSet) GenericDataSourceException(org.apache.ofbiz.entity.GenericDataSourceException) EntityConditionParam(org.apache.ofbiz.entity.condition.EntityConditionParam)

Example 7 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class GenericDAO method singleUpdateView.

/* ====================================================================== */
/* ====================================================================== */
/**
 * Try to update the given ModelViewEntity by trying to insert/update on the entities of which the view is composed.
 *
 * Works fine with standard O/R mapped models, but has some restrictions meeting more complicated view entities.
 * <li>A direct link is required, which means that one of the ModelViewLink field entries must have a value found
 * in the given view entity, for each ModelViewLink</li>
 * <li>For now, each member entity is updated iteratively, so if eg. the second member entity fails to update,
 * the first is written although. See code for details. Try to use "clean" views, until code is more robust ...</li>
 * <li>For now, aliased field names in views are not processed correctly, I guess. To be honest, I did not
 * find out how to construct such a view - so view fieldnames must have same named fields in member entities.</li>
 * <li>A new exception, e.g. GenericViewNotUpdatable, should be defined and thrown if the update fails</li>
 */
private int singleUpdateView(GenericEntity entity, ModelViewEntity modelViewEntity, List<ModelField> fieldsToSave, SQLProcessor sqlP) throws GenericEntityException {
    Delegator delegator = entity.getDelegator();
    int retVal = 0;
    ModelEntity memberModelEntity = null;
    // Construct insert/update for each model entity
    for (ModelViewEntity.ModelMemberEntity modelMemberEntity : modelViewEntity.getMemberModelMemberEntities().values()) {
        String meName = modelMemberEntity.getEntityName();
        String meAlias = modelMemberEntity.getEntityAlias();
        if (Debug.verboseOn())
            Debug.logVerbose("[singleUpdateView]: Processing MemberEntity " + meName + " with Alias " + meAlias, module);
        try {
            memberModelEntity = delegator.getModelReader().getModelEntity(meName);
        } catch (GenericEntityException e) {
            throw new GenericEntityException("Failed to get model entity for " + meName, e);
        }
        Map<String, Object> findByMap = new HashMap<String, Object>();
        // Now iterate the ModelViewLinks to construct the "WHERE" part for update/insert
        Iterator<ModelViewEntity.ModelViewLink> linkIter = modelViewEntity.getViewLinksIterator();
        while (linkIter != null && linkIter.hasNext()) {
            ModelViewEntity.ModelViewLink modelViewLink = linkIter.next();
            if (modelViewLink.getEntityAlias().equals(meAlias) || modelViewLink.getRelEntityAlias().equals(meAlias)) {
                Iterator<ModelKeyMap> kmIter = modelViewLink.getKeyMapsIterator();
                while (kmIter != null && kmIter.hasNext()) {
                    ModelKeyMap keyMap = kmIter.next();
                    String fieldName = "";
                    if (modelViewLink.getEntityAlias().equals(meAlias)) {
                        fieldName = keyMap.getFieldName();
                    } else {
                        fieldName = keyMap.getRelFieldName();
                    }
                    if (Debug.verboseOn())
                        Debug.logVerbose("[singleUpdateView]: --- Found field to set: " + meAlias + "." + fieldName, module);
                    Object value = null;
                    if (modelViewEntity.isField(keyMap.getFieldName())) {
                        value = entity.get(keyMap.getFieldName());
                        if (Debug.verboseOn())
                            Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
                    } else if (modelViewEntity.isField(keyMap.getRelFieldName())) {
                        value = entity.get(keyMap.getRelFieldName());
                        if (Debug.verboseOn())
                            Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
                    } else {
                        throw new GenericNotImplementedException("Update on view entities: no direct link found, unable to update");
                    }
                    findByMap.put(fieldName, value);
                }
            }
        }
        // Look what there already is in the database
        List<GenericValue> meResult = null;
        try {
            meResult = EntityQuery.use(delegator).from(meName).where(findByMap).queryList();
        } catch (GenericEntityException e) {
            throw new GenericEntityException("Error while retrieving partial results for entity member: " + meName, e);
        }
        if (Debug.verboseOn())
            Debug.logVerbose("[singleUpdateView]: --- Found " + meResult.size() + " results for entity member " + meName, module);
        // Got results 0 -> INSERT, 1 -> UPDATE, >1 -> View is nor updatable
        GenericValue meGenericValue = null;
        if (meResult.size() == 0) {
            // Create new value to insert
            try {
                // Create new value to store
                meGenericValue = delegator.makeValue(meName, findByMap);
            } catch (Exception e) {
                throw new GenericEntityException("Could not create new value for member entity" + meName + " of view " + modelViewEntity.getEntityName(), e);
            }
        } else if (meResult.size() == 1) {
            // Update existing value
            meGenericValue = meResult.iterator().next();
        } else {
            throw new GenericEntityException("Found more than one result for member entity " + meName + " in view " + modelViewEntity.getEntityName() + " - this is no updatable view");
        }
        // Construct fieldsToSave list for this member entity
        List<ModelField> meFieldsToSave = new LinkedList<ModelField>();
        for (ModelField modelField : fieldsToSave) {
            if (memberModelEntity.isField(modelField.getName())) {
                ModelField meModelField = memberModelEntity.getField(modelField.getName());
                if (meModelField != null) {
                    meGenericValue.set(meModelField.getName(), entity.get(modelField.getName()));
                    meFieldsToSave.add(meModelField);
                    if (Debug.verboseOn())
                        Debug.logVerbose("[singleUpdateView]: --- Added field to save: " + meModelField.getName() + " with value " + meGenericValue.get(meModelField.getName()), module);
                } else {
                    throw new GenericEntityException("Could not get field " + modelField.getName() + " from model entity " + memberModelEntity.getEntityName());
                }
            }
        }
        /*
             * Finally, do the insert/update
             * TODO:
             * Do the real inserts/updates outside the memberEntity-loop,
             * only if all of the found member entities are updatable.
             * This avoids partial creation of member entities, which would mean data inconsistency:
             * If not all member entities can be updated, then none should be updated
             */
        if (meResult.size() == 0) {
            retVal += singleInsert(meGenericValue, memberModelEntity, memberModelEntity.getFieldsUnmodifiable(), sqlP);
        } else {
            if (meFieldsToSave.size() > 0) {
                retVal += singleUpdate(meGenericValue, memberModelEntity, meFieldsToSave, sqlP);
            } else {
                if (Debug.verboseOn())
                    Debug.logVerbose("[singleUpdateView]: No update on member entity " + memberModelEntity.getEntityName() + " needed", module);
            }
        }
    }
    return retVal;
}
Also used : GenericValue(org.apache.ofbiz.entity.GenericValue) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GenericNotImplementedException(org.apache.ofbiz.entity.GenericNotImplementedException) SQLException(java.sql.SQLException) GenericDataSourceException(org.apache.ofbiz.entity.GenericDataSourceException) GenericNotImplementedException(org.apache.ofbiz.entity.GenericNotImplementedException) EntityLockedException(org.apache.ofbiz.entity.EntityLockedException) GenericModelException(org.apache.ofbiz.entity.GenericModelException) GenericEntityNotFoundException(org.apache.ofbiz.entity.GenericEntityNotFoundException) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) LinkedList(java.util.LinkedList) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap) Delegator(org.apache.ofbiz.entity.Delegator) ModelField(org.apache.ofbiz.entity.model.ModelField) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 8 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class GenericEntity method set.

/**
 * Sets the named field to the passed value. If value is null, it is only
 *  set if the setIfNull parameter is true. This is useful because an update
 *  will only set values that are included in the HashMap and will store null
 *  values in the HashMap to the datastore. If a value is not in the HashMap,
 *  it will be left unmodified in the datastore.
 * @param name The field name to set
 * @param value The value to set
 * @param setIfNull Specifies whether or not to set the value if it is null
 */
public Object set(String name, Object value, boolean setIfNull) {
    assertIsMutable();
    ModelField modelField = getModelEntity().getField(name);
    if (modelField == null) {
        throw new IllegalArgumentException("[GenericEntity.set] \"" + name + "\" is not a field of " + entityName + ", must be one of: " + getModelEntity().fieldNameString());
    }
    if (value != null || setIfNull) {
        ModelFieldType type = null;
        try {
            type = getDelegator().getEntityFieldType(getModelEntity(), modelField.getType());
        } catch (IllegalStateException | GenericEntityException e) {
            Debug.logWarning(e, module);
        }
        if (type == null) {
            throw new IllegalArgumentException("Type " + modelField.getType() + " not found for entity [" + this.getEntityName() + "]; probably because there is no datasource (helper) setup for the entity group that this entity is in: [" + this.getDelegator().getEntityGroupName(this.getEntityName()) + "]");
        }
        if (value instanceof Boolean) {
            // if this is a Boolean check to see if we should convert from an indicator or just leave as is
            try {
                int fieldType = SqlJdbcUtil.getType(type.getJavaType());
                if (fieldType != 10) {
                    value = ((Boolean) value).booleanValue() ? "Y" : "N";
                }
            } catch (GenericNotImplementedException e) {
                throw new IllegalArgumentException(e.getMessage());
            }
        } else if (value != null && !(value instanceof NULL)) {
            // make sure the type matches the field Java type
            if (value instanceof TimeDuration) {
                try {
                    value = ObjectType.simpleTypeConvert(value, type.getJavaType(), null, null);
                } catch (GeneralException e) {
                    Debug.logError(e, module);
                }
            } else if ((value instanceof String) && "byte[]".equals(type.getJavaType())) {
                value = ((String) value).getBytes(UtilIO.getUtf8());
            }
            if (!ObjectType.instanceOf(value, type.getJavaType())) {
                if (!("java.sql.Blob".equals(type.getJavaType()) && (value instanceof byte[] || ObjectType.instanceOf(value, ByteBuffer.class)))) {
                    String errMsg = "In entity field [" + this.getEntityName() + "." + name + "] set the value passed in [" + value.getClass().getName() + "] is not compatible with the Java type of the field [" + type.getJavaType() + "]";
                    // eventually we should do this, but for now we'll do a "soft" failure: throw new IllegalArgumentException(errMsg);
                    Debug.logWarning(new Exception("Location of database type warning"), "=-=-=-=-=-=-=-=-= Database type warning GenericEntity.set =-=-=-=-=-=-=-=-= " + errMsg, module);
                }
            }
        }
        Object old = fields.put(name, value);
        generateHashCode = true;
        this.setChanged();
        this.notifyObservers(name);
        return old;
    }
    return fields.get(name);
}
Also used : GeneralException(org.apache.ofbiz.base.util.GeneralException) SQLException(java.sql.SQLException) MissingResourceException(java.util.MissingResourceException) GeneralException(org.apache.ofbiz.base.util.GeneralException) ModelField(org.apache.ofbiz.entity.model.ModelField) ModelFieldType(org.apache.ofbiz.entity.model.ModelFieldType) TimeDuration(org.apache.ofbiz.base.util.TimeDuration)

Example 9 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class GenericEntity method makeXmlElement.

/**
 * Makes an XML Element object with an attribute for each field of the entity
 *@param document The XML Document that the new Element will be part of
 *@param prefix A prefix to put in front of the entity name in the tag name
 *@return org.w3c.dom.Element object representing this generic entity
 */
public Element makeXmlElement(Document document, String prefix) {
    Element element = null;
    if (prefix == null) {
        prefix = "";
    }
    if (document != null) {
        element = document.createElement(prefix + this.getEntityName());
    }
    if (element == null) {
        return null;
    }
    Iterator<ModelField> modelFields = this.getModelEntity().getFieldsIterator();
    while (modelFields.hasNext()) {
        ModelField modelField = modelFields.next();
        String name = modelField.getName();
        String value = this.getString(name);
        if (value != null) {
            if (value.indexOf('\n') >= 0 || value.indexOf('\r') >= 0) {
                UtilXml.addChildElementCDATAValue(element, name, value, document);
            } else {
                element.setAttribute(name, value);
            }
        }
    }
    return element;
}
Also used : ModelField(org.apache.ofbiz.entity.model.ModelField) Element(org.w3c.dom.Element)

Example 10 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class GenericEntity method compareTo.

/**
 * Compares this GenericEntity to the passed object
 *@param that Object to compare this to
 *@return int representing the result of the comparison (-1,0, or 1)
 */
public int compareTo(GenericEntity that) {
    // if null, it will push to the beginning
    if (that == null) {
        return -1;
    }
    int tempResult = this.entityName.compareTo(that.entityName);
    // if they did not match, we know the order, otherwise compare the primary keys
    if (tempResult != 0) {
        return tempResult;
    }
    // both have same entityName, should be the same so let's compare PKs
    Iterator<ModelField> pkIter = getModelEntity().getPksIterator();
    while (pkIter.hasNext()) {
        ModelField curField = pkIter.next();
        tempResult = compareToFields(that, curField.getName());
        if (tempResult != 0) {
            return tempResult;
        }
    }
    // okay, if we got here it means the primaryKeys are exactly the SAME, so compare the rest of the fields
    Iterator<ModelField> nopkIter = getModelEntity().getNopksIterator();
    while (nopkIter.hasNext()) {
        ModelField curField = nopkIter.next();
        if (!curField.getIsAutoCreatedInternal()) {
            tempResult = compareToFields(that, curField.getName());
            if (tempResult != 0) {
                return tempResult;
            }
        }
    }
    // if we got here it means the two are exactly the same, so return tempResult, which should be 0
    return tempResult;
}
Also used : ModelField(org.apache.ofbiz.entity.model.ModelField)

Aggregations

ModelField (org.apache.ofbiz.entity.model.ModelField)55 ModelEntity (org.apache.ofbiz.entity.model.ModelEntity)28 GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)16 LinkedList (java.util.LinkedList)14 ModelViewEntity (org.apache.ofbiz.entity.model.ModelViewEntity)13 HashMap (java.util.HashMap)10 GenericValue (org.apache.ofbiz.entity.GenericValue)10 ModelFieldType (org.apache.ofbiz.entity.model.ModelFieldType)10 ModelKeyMap (org.apache.ofbiz.entity.model.ModelKeyMap)10 Map (java.util.Map)8 SQLException (java.sql.SQLException)7 Locale (java.util.Locale)7 GenericModelException (org.apache.ofbiz.entity.GenericModelException)7 TreeSet (java.util.TreeSet)6 Delegator (org.apache.ofbiz.entity.Delegator)6 EntityCondition (org.apache.ofbiz.entity.condition.EntityCondition)6 GeneralException (org.apache.ofbiz.base.util.GeneralException)5 ModelParam (org.apache.ofbiz.service.ModelParam)5 SQLProcessor (org.apache.ofbiz.entity.jdbc.SQLProcessor)4 GenericServiceException (org.apache.ofbiz.service.GenericServiceException)4