Search in sources :

Example 76 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class ObjectDiff method isNoop.

/**
 * Checks whether at least a single property is modified.
 */
@Override
public boolean isNoop() {
    // if we have no baseline to compare with, assume that there are changes
    if (snapshot == null) {
        return false;
    }
    if (flatIds != null && !flatIds.isEmpty()) {
        return false;
    }
    if (phantomFks != null && !phantomFks.isEmpty()) {
        return false;
    }
    int state = object.getPersistenceState();
    if (state == PersistenceState.NEW || state == PersistenceState.DELETED) {
        return false;
    }
    // check phantom mods
    final boolean[] modFound = new boolean[1];
    getClassDescriptor().visitProperties(new PropertyVisitor() {

        @Override
        public boolean visitAttribute(AttributeProperty property) {
            Object oldValue = snapshot.get(property.getName());
            Object newValue = property.readProperty(object);
            if (!Util.nullSafeEquals(oldValue, newValue)) {
                modFound[0] = true;
            }
            return !modFound[0];
        }

        @Override
        public boolean visitToMany(ToManyProperty property) {
            // flattened changes
            return true;
        }

        @Override
        public boolean visitToOne(ToOneProperty property) {
            if (arcSnapshot == null) {
                return true;
            }
            Object newValue = property.readPropertyDirectly(object);
            if (newValue instanceof Fault) {
                return true;
            }
            Object oldValue = arcSnapshot.get(property.getName());
            if (!Util.nullSafeEquals(oldValue, newValue != null ? ((Persistent) newValue).getObjectId() : null)) {
                modFound[0] = true;
            }
            return !modFound[0];
        }
    });
    return !modFound[0];
}
Also used : ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Fault(org.apache.cayenne.Fault) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 77 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class ObjectResolver method objectFromDataRow.

Persistent objectFromDataRow(DataRow row, ObjectId anId, ClassDescriptor classDescriptor) {
    // details
    if (anId == null) {
        return null;
    }
    // this will create a HOLLOW object if it is not registered yet
    Persistent object = context.findOrCreateObject(anId);
    // deal with object state
    int state = object.getPersistenceState();
    switch(state) {
        case PersistenceState.COMMITTED:
        case PersistenceState.MODIFIED:
        case PersistenceState.DELETED:
            // process the above only if refresh is requested...
            if (refreshObjects) {
                DataRowUtils.mergeObjectWithSnapshot(context, classDescriptor, object, row);
                if (object instanceof DataObject) {
                    ((DataObject) object).setSnapshotVersion(row.getVersion());
                }
            }
            break;
        case PersistenceState.HOLLOW:
            if (!refreshObjects) {
                DataRow cachedRow = cache.getCachedSnapshot(anId);
                if (cachedRow != null) {
                    row = cachedRow;
                }
            }
            DataRowUtils.mergeObjectWithSnapshot(context, classDescriptor, object, row);
            if (object instanceof DataObject) {
                ((DataObject) object).setSnapshotVersion(row.getVersion());
            }
            break;
        default:
            break;
    }
    return object;
}
Also used : DataObject(org.apache.cayenne.DataObject) Persistent(org.apache.cayenne.Persistent) DataRow(org.apache.cayenne.DataRow)

Example 78 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class ObjectStore method objectsRolledBack.

/**
 * Reverts changes to all stored uncomitted objects.
 *
 * @since 1.1
 */
public synchronized void objectsRolledBack() {
    Iterator<Persistent> it = getObjectIterator();
    // collect candidates
    while (it.hasNext()) {
        Persistent object = it.next();
        int objectState = object.getPersistenceState();
        switch(objectState) {
            case PersistenceState.NEW:
                it.remove();
                object.setObjectContext(null);
                object.setObjectId(null);
                object.setPersistenceState(PersistenceState.TRANSIENT);
                break;
            case PersistenceState.DELETED:
            // rolling the object back will set the state to committed
            case PersistenceState.MODIFIED:
                // this will clean any modifications and defer refresh from snapshot
                // till the next object accessor is called
                object.setPersistenceState(PersistenceState.HOLLOW);
                break;
            default:
                // Transient, committed and hollow need no handling
                break;
        }
    }
    // reset changes ... using new HashMap to allow event listeners to analyze the
    // original changes map after the rollback
    this.changes = new HashMap<>();
}
Also used : Persistent(org.apache.cayenne.Persistent)

Example 79 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class ObjectStore method registerDiff.

/**
 * Registers object change.
 *
 * @since 1.2
 */
synchronized ObjectDiff registerDiff(Object nodeId, NodeDiff diff) {
    if (diff != null) {
        diff.setDiffId(++currentDiffId);
    }
    ObjectDiff objectDiff = changes.get(nodeId);
    if (objectDiff == null) {
        Persistent object = objectMap.get(nodeId);
        if (object == null) {
            throw new CayenneRuntimeException("No object is registered in context with Id %s", nodeId);
        }
        if (object.getPersistenceState() == PersistenceState.COMMITTED) {
            object.setPersistenceState(PersistenceState.MODIFIED);
            // replacement yet, so we still need to handle them...
            if (object instanceof DataObject) {
                DataObject dataObject = (DataObject) object;
                DataRow snapshot = getCachedSnapshot((ObjectId) nodeId);
                if (snapshot != null && snapshot.getVersion() != dataObject.getSnapshotVersion()) {
                    DataContextDelegate delegate = context.nonNullDelegate();
                    if (delegate.shouldMergeChanges(dataObject, snapshot)) {
                        ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
                        DataRowUtils.forceMergeWithSnapshot(context, descriptor, dataObject, snapshot);
                        dataObject.setSnapshotVersion(snapshot.getVersion());
                        delegate.finishedMergeChanges(dataObject);
                    }
                }
            }
        }
        objectDiff = new ObjectDiff(object);
        objectDiff.setDiffId(++currentDiffId);
        changes.put(nodeId, objectDiff);
    }
    if (diff != null) {
        objectDiff.addDiff(diff, this);
    }
    return objectDiff;
}
Also used : DataObject(org.apache.cayenne.DataObject) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) Persistent(org.apache.cayenne.Persistent) DataRow(org.apache.cayenne.DataRow)

Example 80 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class DefaultSelectTranslator method appendOverriddenColumns.

/**
 * If query contains explicit column list, use only them
 */
<T> List<ColumnDescriptor> appendOverriddenColumns(List<ColumnDescriptor> columns, SelectQuery<T> query) {
    groupByColumns = new HashMap<>();
    QualifierTranslator qualifierTranslator = adapter.getQualifierTranslator(this);
    AccumulatingBindingListener bindingListener = new AccumulatingBindingListener();
    final String[] joinTableAliasForProperty = { null };
    // capture last alias for joined table, will use it to resolve object columns
    joinListener = () -> joinTableAliasForProperty[0] = getCurrentAlias();
    setAddBindingListener(bindingListener);
    for (Property<?> property : query.getColumns()) {
        joinTableAliasForProperty[0] = null;
        int expressionType = property.getExpression().getType();
        // forbid direct selection of toMany relationships columns
        if (property.getType() != null && (expressionType == Expression.OBJ_PATH || expressionType == Expression.DB_PATH) && (Collection.class.isAssignableFrom(property.getType()) || Map.class.isAssignableFrom(property.getType()))) {
            throw new CayenneRuntimeException("Can't directly select toMany relationship columns. " + "Either select it with aggregate functions like count() or with flat() function to select full related objects.");
        }
        // evaluate ObjPath with Persistent type as toOne relations and use it as full object
        boolean objectProperty = expressionType == Expression.FULL_OBJECT || (property.getType() != null && expressionType == Expression.OBJ_PATH && Persistent.class.isAssignableFrom(property.getType()));
        // Qualifier Translator in case of Object Columns have side effect -
        // it will create required joins, that we catch with listener above.
        // And we force created join alias for all columns of Object we select.
        qualifierTranslator.setQualifier(property.getExpression());
        qualifierTranslator.setForceJoinForRelations(objectProperty);
        StringBuilder builder = qualifierTranslator.appendPart(new StringBuilder());
        if (objectProperty) {
            // If we want full object, use appendQueryColumns method, to fully process class descriptor
            List<ColumnDescriptor> classColumns = new ArrayList<>();
            ObjEntity entity = entityResolver.getObjEntity(property.getType());
            if (getQueryMetadata().getPageSize() > 0) {
                appendIdColumns(classColumns, entity);
            } else {
                ClassDescriptor classDescriptor = entityResolver.getClassDescriptor(entity.getName());
                appendQueryColumns(classColumns, query, classDescriptor, joinTableAliasForProperty[0]);
            }
            for (ColumnDescriptor descriptor : classColumns) {
                columns.add(descriptor);
                groupByColumns.put(descriptor, Collections.<DbAttributeBinding>emptyList());
            }
        } else {
            // This property will go as scalar value
            String alias = property.getAlias();
            if (alias != null) {
                builder.append(" AS ").append(alias);
            }
            int type = getJdbcTypeForProperty(property);
            ColumnDescriptor descriptor;
            if (property.getType() != null) {
                descriptor = new ColumnDescriptor(builder.toString(), type, property.getType().getCanonicalName());
            } else {
                descriptor = new ColumnDescriptor(builder.toString(), type);
            }
            descriptor.setDataRowKey(alias);
            descriptor.setIsExpression(true);
            columns.add(descriptor);
            if (isAggregate(property)) {
                haveAggregate = true;
            } else {
                groupByColumns.put(descriptor, bindingListener.getBindings());
            }
            bindingListener.reset();
        }
    }
    setAddBindingListener(null);
    qualifierTranslator.setForceJoinForRelations(false);
    joinListener = null;
    return columns;
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ColumnDescriptor(org.apache.cayenne.access.jdbc.ColumnDescriptor) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ArrayList(java.util.ArrayList) Persistent(org.apache.cayenne.Persistent) ObjEntity(org.apache.cayenne.map.ObjEntity) Collection(java.util.Collection) Map(java.util.Map) HashMap(java.util.HashMap) DataMap(org.apache.cayenne.map.DataMap)

Aggregations

Persistent (org.apache.cayenne.Persistent)88 ObjectId (org.apache.cayenne.ObjectId)38 Test (org.junit.Test)32 ArrayList (java.util.ArrayList)17 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)17 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)17 DataObject (org.apache.cayenne.DataObject)13 Map (java.util.Map)12 ObjEntity (org.apache.cayenne.map.ObjEntity)10 EJBQLQuery (org.apache.cayenne.query.EJBQLQuery)10 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)10 DataRow (org.apache.cayenne.DataRow)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)8 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)8 Collection (java.util.Collection)7 HashMap (java.util.HashMap)7 ObjectContext (org.apache.cayenne.ObjectContext)6 DbEntity (org.apache.cayenne.map.DbEntity)6 List (java.util.List)5