Search in sources :

Example 1 with DbRowOpWithValues

use of org.apache.cayenne.access.flush.operation.DbRowOpWithValues in project cayenne by apache.

the class ArcValuesCreationHandler method processFlattenedPath.

ObjectId processFlattenedPath(ObjectId id, ObjectId finalTargetId, DbEntity entity, String dbPath, boolean add) {
    Iterator<CayenneMapEntry> dbPathIterator = entity.resolvePathComponents(dbPath);
    StringBuilder path = new StringBuilder();
    ObjectId srcId = id;
    ObjectId targetId = null;
    while (dbPathIterator.hasNext()) {
        CayenneMapEntry entry = dbPathIterator.next();
        if (path.length() > 0) {
            path.append('.');
        }
        path.append(entry.getName());
        if (entry instanceof DbRelationship) {
            DbRelationship relationship = (DbRelationship) entry;
            // intermediate db entity to be inserted
            DbEntity target = relationship.getTargetEntity();
            // if ID is present, just use it, otherwise create new
            String flattenedPath = path.toString();
            // if this is last segment and it's a relationship, use known target id from arc creation
            if (!dbPathIterator.hasNext()) {
                targetId = finalTargetId;
            } else {
                if (!relationship.isToMany()) {
                    targetId = factory.getStore().getFlattenedId(id, flattenedPath);
                } else {
                    targetId = null;
                }
            }
            if (targetId == null) {
                // should insert, regardless of original operation (insert/update)
                targetId = ObjectId.of(ASTDbPath.DB_PREFIX + target.getName());
                if (!relationship.isToMany()) {
                    factory.getStore().markFlattenedPath(id, flattenedPath, targetId);
                }
                DbRowOpType type;
                if (relationship.isToMany()) {
                    type = add ? DbRowOpType.INSERT : DbRowOpType.DELETE;
                    factory.getOrCreate(target, targetId, type);
                } else {
                    type = add ? DbRowOpType.INSERT : DbRowOpType.UPDATE;
                    factory.<DbRowOpWithValues>getOrCreate(target, targetId, type).getValues().addFlattenedId(flattenedPath, targetId);
                }
            } else if (dbPathIterator.hasNext()) {
                // should update existing DB row
                factory.getOrCreate(target, targetId, add ? DbRowOpType.UPDATE : defaultType);
            }
            processRelationship(relationship, srcId, targetId, add);
            // use target as next source..
            srcId = targetId;
        }
    }
    return targetId;
}
Also used : CayenneMapEntry(org.apache.cayenne.util.CayenneMapEntry) DbEntity(org.apache.cayenne.map.DbEntity) ObjectId(org.apache.cayenne.ObjectId) DbRowOpType(org.apache.cayenne.access.flush.operation.DbRowOpType) DbRelationship(org.apache.cayenne.map.DbRelationship) DbRowOpWithValues(org.apache.cayenne.access.flush.operation.DbRowOpWithValues)

Example 2 with DbRowOpWithValues

use of org.apache.cayenne.access.flush.operation.DbRowOpWithValues in project cayenne by apache.

the class ValuesCreationHandler method nodePropertyChanged.

@Override
public void nodePropertyChanged(Object nodeId, String property, Object oldValue, Object newValue) {
    ObjectId id = (ObjectId) nodeId;
    ObjEntity entity = factory.getDescriptor().getEntity();
    if (entity.isReadOnly()) {
        throw new CayenneRuntimeException("Attempt to modify object(s) mapped to a read-only entity: '%s'. " + "Can't commit changes.", entity.getName());
    }
    ObjAttribute attribute = entity.getAttribute(property);
    DbEntity dbEntity = entity.getDbEntity();
    if (attribute.isFlattened()) {
        // get target row ID
        id = processFlattenedPath(id, null, dbEntity, attribute.getDbAttributePath(), newValue != null);
    }
    if (id == null) {
        // some extra safety, shouldn't happen
        throw new CayenneRuntimeException("Unable to resolve DB row PK for object's %s update of property '%s'", nodeId, property);
    }
    DbAttribute dbAttribute = attribute.getDbAttribute();
    if (dbAttribute.isPrimaryKey()) {
        if (!(newValue instanceof Number) || ((Number) newValue).longValue() != 0) {
            id.getReplacementIdMap().put(dbAttribute.getName(), newValue);
        }
    }
    DbRowOpWithValues dbRow = factory.get(id);
    if (dbRow != null) {
        dbRow.getValues().addValue(dbAttribute, newValue, false);
    }
}
Also used : ObjEntity(org.apache.cayenne.map.ObjEntity) ObjAttribute(org.apache.cayenne.map.ObjAttribute) DbEntity(org.apache.cayenne.map.DbEntity) ObjectId(org.apache.cayenne.ObjectId) DbRowOpWithValues(org.apache.cayenne.access.flush.operation.DbRowOpWithValues) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbAttribute(org.apache.cayenne.map.DbAttribute)

Aggregations

ObjectId (org.apache.cayenne.ObjectId)2 DbRowOpWithValues (org.apache.cayenne.access.flush.operation.DbRowOpWithValues)2 DbEntity (org.apache.cayenne.map.DbEntity)2 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)1 DbRowOpType (org.apache.cayenne.access.flush.operation.DbRowOpType)1 DbAttribute (org.apache.cayenne.map.DbAttribute)1 DbRelationship (org.apache.cayenne.map.DbRelationship)1 ObjAttribute (org.apache.cayenne.map.ObjAttribute)1 ObjEntity (org.apache.cayenne.map.ObjEntity)1 CayenneMapEntry (org.apache.cayenne.util.CayenneMapEntry)1