Search in sources :

Example 16 with ModelEntity

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

the class GenericDAO method partialSelect.

public void partialSelect(GenericEntity entity, Set<String> keys) throws GenericEntityException {
    ModelEntity modelEntity = entity.getModelEntity();
    if (modelEntity instanceof ModelViewEntity) {
        throw new org.apache.ofbiz.entity.GenericNotImplementedException("Operation partialSelect not supported yet for view entities");
    }
    // we don't want to select ALL fields, just the nonpk fields that are in the passed GenericEntity
    List<ModelField> partialFields = new LinkedList<ModelField>();
    Set<String> tempKeys = new TreeSet<String>(keys);
    Iterator<ModelField> entityFieldIter = modelEntity.getFieldsIterator();
    while (entityFieldIter.hasNext()) {
        ModelField curField = entityFieldIter.next();
        if (tempKeys.contains(curField.getName())) {
            partialFields.add(curField);
            tempKeys.remove(curField.getName());
        }
    }
    if (tempKeys.size() > 0) {
        throw new GenericModelException("In partialSelect invalid field names specified: " + tempKeys.toString());
    }
    StringBuilder sqlBuffer = new StringBuilder("SELECT ");
    if (partialFields.size() > 0) {
        modelEntity.colNameString(partialFields, sqlBuffer, "", ", ", "", datasource.getAliasViewColumns());
    } else {
        sqlBuffer.append("*");
    }
    sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, modelFieldTypeReader, datasource));
    sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPkFieldsUnmodifiable(), entity, "AND", datasource.getJoinStyle()));
    try (SQLProcessor sqlP = new SQLProcessor(entity.getDelegator(), helperInfo)) {
        sqlP.prepareStatement(sqlBuffer.toString(), true, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity, modelFieldTypeReader);
        sqlP.executeQuery();
        if (sqlP.next()) {
            for (int j = 0; j < partialFields.size(); j++) {
                ModelField curField = partialFields.get(j);
                SqlJdbcUtil.getValue(sqlP.getResultSet(), j + 1, curField, entity, modelFieldTypeReader);
            }
            entity.synchronizedWithDatasource();
        } else {
            throw new GenericEntityNotFoundException("Result set was empty for entity: " + entity.toString());
        }
    }
}
Also used : GenericModelException(org.apache.ofbiz.entity.GenericModelException) GenericNotImplementedException(org.apache.ofbiz.entity.GenericNotImplementedException) LinkedList(java.util.LinkedList) SQLProcessor(org.apache.ofbiz.entity.jdbc.SQLProcessor) ModelField(org.apache.ofbiz.entity.model.ModelField) TreeSet(java.util.TreeSet) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) GenericEntityNotFoundException(org.apache.ofbiz.entity.GenericEntityNotFoundException) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 17 with ModelEntity

use of org.apache.ofbiz.entity.model.ModelEntity 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 18 with ModelEntity

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

the class GenericEntity method get.

/**
 * call by the previous method to be able to read with View entityName and entity Field and after for real entity
 * @param modelEntity the modelEntity, for a view it's the ViewEntity
 * @param modelEntityToUse, same as before except if it's a second call for a view, and so it's the real modelEntity
 * @return null or resourceValue
 */
private Object get(ModelEntity modelEntity, ModelEntity modelEntityToUse, String name, String resource, Locale locale) {
    if (UtilValidate.isEmpty(resource)) {
        resource = modelEntityToUse.getDefaultResourceName();
        // still empty? return null
        if (UtilValidate.isEmpty(resource)) {
            return null;
        }
    }
    if (UtilProperties.isPropertiesResourceNotFound(resource, locale, false)) {
        // Properties do not exist for this resource+locale combination
        return null;
    }
    ResourceBundle bundle = null;
    try {
        bundle = UtilProperties.getResourceBundle(resource, locale);
    } catch (IllegalArgumentException e) {
        bundle = null;
    }
    if (bundle == null) {
        return null;
    }
    StringBuilder keyBuffer = new StringBuilder();
    // start with the Entity Name
    keyBuffer.append(modelEntityToUse.getEntityName());
    // next add the Field Name
    keyBuffer.append('.');
    keyBuffer.append(name);
    // finish off by adding the values of all PK fields
    if (modelEntity instanceof ModelViewEntity) {
        // retrieve pkNames of realEntity
        ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
        List<String> pkNamesToUse = new LinkedList<>();
        // iterate on realEntity for pkField
        Iterator<ModelField> iter = modelEntityToUse.getPksIterator();
        while (iter != null && iter.hasNext()) {
            ModelField curField = iter.next();
            String pkName = null;
            Iterator<ModelAlias> iterAlias = modelViewEntity.getAliasesIterator();
            // search aliasName for pkField of realEntity
            while (iterAlias != null && iterAlias.hasNext()) {
                ModelAlias aliasField = iterAlias.next();
                if (aliasField.getField().equals(curField.getName())) {
                    ModelEntity memberModelEntity = modelViewEntity.getMemberModelEntity(aliasField.getEntityAlias());
                    if (memberModelEntity.getEntityName().equals(modelEntityToUse.getEntityName())) {
                        pkName = aliasField.getName();
                        break;
                    }
                }
            }
            if (pkName == null) {
                pkName = curField.getName();
            }
            pkNamesToUse.add(pkName);
        }
        // read value with modelEntity name of pkNames
        for (String pkName : pkNamesToUse) {
            if (this.containsKey(pkName)) {
                keyBuffer.append('.');
                keyBuffer.append(this.get(pkName));
            }
        }
    } else {
        Iterator<ModelField> iter = modelEntity.getPksIterator();
        while (iter != null && iter.hasNext()) {
            ModelField curField = iter.next();
            keyBuffer.append('.');
            keyBuffer.append(this.get(curField.getName()));
        }
    }
    String bundleKey = keyBuffer.toString();
    Object resourceValue = null;
    try {
        resourceValue = bundle.getObject(bundleKey);
    } catch (MissingResourceException e) {
        return null;
    }
    return resourceValue;
}
Also used : ModelAlias(org.apache.ofbiz.entity.model.ModelViewEntity.ModelAlias) MissingResourceException(java.util.MissingResourceException) LinkedList(java.util.LinkedList) ModelField(org.apache.ofbiz.entity.model.ModelField) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ResourceBundle(java.util.ResourceBundle) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 19 with ModelEntity

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

the class AbstractEntityConditionCache method getModelCheckValid.

protected ModelEntity getModelCheckValid(GenericEntity oldEntity, GenericEntity newEntity) {
    ModelEntity model;
    if (!isNull(newEntity)) {
        model = newEntity.getModelEntity();
        String entityName = model.getEntityName();
        if (oldEntity != null && !entityName.equals(oldEntity.getEntityName())) {
            throw new IllegalArgumentException("internal error: storeHook called with 2 different entities(old=" + oldEntity.getEntityName() + ", new=" + entityName + ")");
        }
    } else {
        if (!isNull(oldEntity)) {
            model = oldEntity.getModelEntity();
        } else {
            throw new IllegalArgumentException("internal error: storeHook called with 2 null arguments");
        }
    }
    return model;
}
Also used : ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 20 with ModelEntity

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

the class AbstractEntityConditionCache method storeHook.

public void storeHook(boolean isPK, GenericEntity oldEntity, GenericEntity newEntity) {
    ModelEntity model = getModelCheckValid(oldEntity, newEntity);
    String entityName = model.getEntityName();
    // for info about cache clearing
    storeHook(entityName, isPK, UtilMisc.toList(oldEntity), UtilMisc.toList(newEntity));
    Iterator<String> it = model.getViewConvertorsIterator();
    while (it.hasNext()) {
        String targetEntityName = it.next();
        storeHook(targetEntityName, isPK, convert(targetEntityName, oldEntity), convert(targetEntityName, newEntity));
    }
}
Also used : ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Aggregations

ModelEntity (org.apache.ofbiz.entity.model.ModelEntity)102 GenericValue (org.apache.ofbiz.entity.GenericValue)37 GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)29 ModelField (org.apache.ofbiz.entity.model.ModelField)28 HashMap (java.util.HashMap)22 Delegator (org.apache.ofbiz.entity.Delegator)17 ModelViewEntity (org.apache.ofbiz.entity.model.ModelViewEntity)16 LinkedList (java.util.LinkedList)14 Locale (java.util.Locale)12 ModelKeyMap (org.apache.ofbiz.entity.model.ModelKeyMap)11 ArrayList (java.util.ArrayList)10 ModelRelation (org.apache.ofbiz.entity.model.ModelRelation)10 IOException (java.io.IOException)8 TreeSet (java.util.TreeSet)8 GenericServiceException (org.apache.ofbiz.service.GenericServiceException)8 Map (java.util.Map)7 GeneralRuntimeException (org.apache.ofbiz.base.util.GeneralRuntimeException)7 EntityCondition (org.apache.ofbiz.entity.condition.EntityCondition)7 ModelFieldType (org.apache.ofbiz.entity.model.ModelFieldType)7 GenericTransactionException (org.apache.ofbiz.entity.transaction.GenericTransactionException)7