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;
}
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);
}
}
Aggregations