Search in sources :

Example 61 with ClassDescriptor

use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.

the class DataContext method objectFromDataRow.

/**
 * Creates a DataObject from DataRow. This variety of the
 * 'objectFromDataRow' method is normally used for generic classes.
 *
 * @see DataRow
 * @since 3.1
 */
public DataObject objectFromDataRow(String entityName, DataRow dataRow) {
    ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entityName);
    List<?> list = objectsFromDataRows(descriptor, Collections.singletonList(dataRow));
    return (DataObject) list.get(0);
}
Also used : DataObject(org.apache.cayenne.DataObject) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor)

Example 62 with ClassDescriptor

use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.

the class DataContext method newObject.

/**
 * Instantiates a new object and registers it with this context. Object
 * class is determined from the mapped entity. Object class must have a
 * default constructor.
 * <p>
 * <i>Note: in most cases {@link #newObject(Class)} method should be used,
 * however this method is helpful when generic persistent classes are
 * used.</i>
 *
 * @since 3.0
 */
public Persistent newObject(String entityName) {
    ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entityName);
    if (descriptor == null) {
        throw new IllegalArgumentException("Invalid entity name: " + entityName);
    }
    Persistent object;
    try {
        object = (Persistent) descriptor.createObject();
    } catch (Exception ex) {
        throw new CayenneRuntimeException("Error instantiating object.", ex);
    }
    // this will initialize to-many lists
    descriptor.injectValueHolders(object);
    ObjectId id = new ObjectId(entityName);
    // note that the order of initialization of persistence artifacts below
    // is
    // important - do not change it lightly
    object.setObjectId(id);
    injectInitialValue(object);
    return object;
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjectId(org.apache.cayenne.ObjectId) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) Persistent(org.apache.cayenne.Persistent) IOException(java.io.IOException) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException)

Example 63 with ClassDescriptor

use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.

the class DataContext method currentSnapshot.

/**
 * Returns a DataRow reflecting current, possibly uncommitted, object state.
 * <p>
 * <strong>Warning:</strong> This method will return a partial snapshot if
 * an object or one of its related objects that propagate their keys to this
 * object have temporary ids. DO NOT USE this method if you expect a DataRow
 * to represent a complete object state.
 * </p>
 *
 * @since 1.1
 */
public DataRow currentSnapshot(final Persistent object) {
    // for a HOLLOW object return snapshot from cache
    if (object.getPersistenceState() == PersistenceState.HOLLOW && object.getObjectContext() != null) {
        return getObjectStore().getSnapshot(object.getObjectId());
    }
    ObjEntity entity = getEntityResolver().getObjEntity(object);
    final ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
    final DataRow snapshot = new DataRow(10);
    snapshot.setEntityName(entity.getName());
    descriptor.visitProperties(new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute objAttr = property.getAttribute();
            // processing compound attributes correctly
            snapshot.put(objAttr.getDbAttributePath(), property.readPropertyDirectly(object));
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            // do nothing
            return true;
        }

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            // if target doesn't propagates its key value, skip it
            if (rel.isSourceIndependentFromTargetChange()) {
                return true;
            }
            Object targetObject = property.readPropertyDirectly(object);
            if (targetObject == null) {
                return true;
            }
            // to avoid unneeded fault triggering
            if (targetObject instanceof Fault) {
                DataRow storedSnapshot = getObjectStore().getSnapshot(object.getObjectId());
                if (storedSnapshot == null) {
                    throw new CayenneRuntimeException("No matching objects found for ObjectId %s" + ". Object may have been deleted externally.", object.getObjectId());
                }
                DbRelationship dbRel = rel.getDbRelationships().get(0);
                for (DbJoin join : dbRel.getJoins()) {
                    String key = join.getSourceName();
                    snapshot.put(key, storedSnapshot.get(key));
                }
                return true;
            }
            // target is resolved and we have an FK->PK to it,
            // so extract it from target...
            Persistent target = (Persistent) targetObject;
            Map<String, Object> idParts = target.getObjectId().getIdSnapshot();
            // this method.
            if (idParts.isEmpty()) {
                return true;
            }
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            Map<String, Object> fk = dbRel.srcFkSnapshotWithTargetSnapshot(idParts);
            snapshot.putAll(fk);
            return true;
        }
    });
    // process object id map
    // we should ignore any object id values if a corresponding attribute
    // is a part of relationship "toMasterPK", since those values have been
    // set above when db relationships where processed.
    Map<String, Object> thisIdParts = object.getObjectId().getIdSnapshot();
    if (thisIdParts != null) {
        // put only those that do not exist in the map
        for (Map.Entry<String, Object> entry : thisIdParts.entrySet()) {
            String nextKey = entry.getKey();
            if (!snapshot.containsKey(nextKey)) {
                snapshot.put(nextKey, entry.getValue());
            }
        }
    }
    return snapshot;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) Fault(org.apache.cayenne.Fault) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) DataRow(org.apache.cayenne.DataRow) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ObjEntity(org.apache.cayenne.map.ObjEntity) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) DataObject(org.apache.cayenne.DataObject) Map(java.util.Map) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 64 with ClassDescriptor

use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.

the class DataDomainSyncBucket method postprocess.

void postprocess() {
    if (!objectsByDescriptor.isEmpty()) {
        CompoundDiff result = parent.getResultDiff();
        Map<ObjectId, DataRow> modifiedSnapshots = parent.getResultModifiedSnapshots();
        Collection<ObjectId> deletedIds = parent.getResultDeletedIds();
        for (Map.Entry<ClassDescriptor, List<Persistent>> entry : objectsByDescriptor.entrySet()) {
            ClassDescriptor descriptor = entry.getKey();
            for (Persistent object : entry.getValue()) {
                ObjectId id = object.getObjectId();
                ObjectId finalId;
                // record id change and update attributes for generated ids
                if (id.isReplacementIdAttached()) {
                    Map<String, Object> replacement = id.getReplacementIdMap();
                    for (AttributeProperty property : descriptor.getIdProperties()) {
                        Object value = replacement.get(property.getAttribute().getDbAttributeName());
                        // if the id wasn't generated. We may need to optimize it...
                        if (value != null) {
                            property.writePropertyDirectly(object, null, value);
                        }
                    }
                    ObjectId replacementId = id.createReplacementId();
                    result.add(new NodeIdChangeOperation(id, replacementId));
                    // DataRowCache has no notion of replaced id...
                    if (!id.isTemporary()) {
                        deletedIds.add(id);
                    }
                    finalId = replacementId;
                } else if (id.isTemporary()) {
                    throw new CayenneRuntimeException("Temporary ID hasn't been replaced on commit: %s", object);
                } else {
                    finalId = id;
                }
                // do not take the snapshot until generated columns are processed (see code above)
                DataRow dataRow = parent.getContext().currentSnapshot(object);
                if (object instanceof DataObject) {
                    DataObject dataObject = (DataObject) object;
                    dataRow.setReplacesVersion(dataObject.getSnapshotVersion());
                    dataObject.setSnapshotVersion(dataRow.getVersion());
                }
                modifiedSnapshots.put(finalId, dataRow);
                // update Map reverse relationships
                for (ArcProperty arc : descriptor.getMapArcProperties()) {
                    ToManyMapProperty reverseArc = (ToManyMapProperty) arc.getComplimentaryReverseArc();
                    // must resolve faults... hopefully for to-one this will not cause extra fetches...
                    Object source = arc.readProperty(object);
                    if (source != null && !reverseArc.isFault(source)) {
                        remapTarget(reverseArc, source, object);
                    }
                }
            }
        }
    }
}
Also used : NodeIdChangeOperation(org.apache.cayenne.graph.NodeIdChangeOperation) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjectId(org.apache.cayenne.ObjectId) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) DataRow(org.apache.cayenne.DataRow) DataObject(org.apache.cayenne.DataObject) ArrayList(java.util.ArrayList) List(java.util.List) DataObject(org.apache.cayenne.DataObject) HashMap(java.util.HashMap) Map(java.util.Map) CompoundDiff(org.apache.cayenne.graph.CompoundDiff)

Example 65 with ClassDescriptor

use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.

the class DataDomainSyncBucket method groupObjEntitiesBySpannedDbEntities.

private void groupObjEntitiesBySpannedDbEntities() {
    dbEntities = new ArrayList<>(objectsByDescriptor.size());
    descriptorsByDbEntity = new HashMap<>(objectsByDescriptor.size() * 2);
    for (ClassDescriptor descriptor : objectsByDescriptor.keySet()) {
        // root DbEntity
        {
            DbEntityClassDescriptor dbEntityDescriptor = new DbEntityClassDescriptor(descriptor);
            DbEntity dbEntity = dbEntityDescriptor.getDbEntity();
            Collection<DbEntityClassDescriptor> descriptors = descriptorsByDbEntity.get(dbEntity);
            if (descriptors == null) {
                descriptors = new ArrayList<>(1);
                dbEntities.add(dbEntity);
                descriptorsByDbEntity.put(dbEntity, descriptors);
            }
            if (!containsClassDescriptor(descriptors, descriptor)) {
                descriptors.add(dbEntityDescriptor);
            }
        }
        // Note that this logic won't allow flattened attributes to span multiple databases...
        for (ObjAttribute objAttribute : descriptor.getEntity().getAttributes()) {
            if (objAttribute.isFlattened()) {
                DbEntityClassDescriptor dbEntityDescriptor = new DbEntityClassDescriptor(descriptor, objAttribute);
                DbEntity dbEntity = dbEntityDescriptor.getDbEntity();
                Collection<DbEntityClassDescriptor> descriptors = descriptorsByDbEntity.get(dbEntity);
                if (descriptors == null) {
                    descriptors = new ArrayList<>(1);
                    dbEntities.add(dbEntity);
                    descriptorsByDbEntity.put(dbEntity, descriptors);
                }
                if (!containsClassDescriptor(descriptors, descriptor)) {
                    descriptors.add(dbEntityDescriptor);
                }
            }
        }
    }
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) DbEntity(org.apache.cayenne.map.DbEntity) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ArrayList(java.util.ArrayList) Collection(java.util.Collection)

Aggregations

ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)81 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)23 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)21 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)21 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)21 ObjEntity (org.apache.cayenne.map.ObjEntity)18 ArcProperty (org.apache.cayenne.reflect.ArcProperty)18 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)17 Persistent (org.apache.cayenne.Persistent)17 ObjectId (org.apache.cayenne.ObjectId)14 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)14 DbRelationship (org.apache.cayenne.map.DbRelationship)13 ObjRelationship (org.apache.cayenne.map.ObjRelationship)12 Test (org.junit.Test)12 ArrayList (java.util.ArrayList)10 DataRow (org.apache.cayenne.DataRow)10 DbAttribute (org.apache.cayenne.map.DbAttribute)10 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)9 DbEntity (org.apache.cayenne.map.DbEntity)9 DbJoin (org.apache.cayenne.map.DbJoin)9