/** * An internal version of {@link #localObject(Object)} that operates on ObjectId instead of * Persistent, and wouldn't attempt to look up an object in the parent channel. * * @since 3.1 */ Persistent findOrCreateObject(ObjectId id) { if (id == null) { throw new IllegalArgumentException("Null ObjectId"); } // have to synchronize almost the entire method to prevent multiple // threads from // messing up dataobjects per CAY-845. Originally only parts of "else" // were // synchronized, but we had to expand the lock scope to ensure // consistent // behavior. synchronized (getGraphManager()) { Persistent cachedObject = (Persistent) getGraphManager().getNode(id); // return an existing object if (cachedObject != null) { int state = cachedObject.getPersistenceState(); // TODO: Andrus, 1/24/2006 implement smart merge for modified // objects... if (state != PersistenceState.MODIFIED && state != PersistenceState.DELETED) { ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName()); descriptor.injectValueHolders(cachedObject); } return cachedObject; } // create and register a hollow object ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName()); Persistent localObject = (Persistent) descriptor.createObject(); localObject.setObjectContext(this); localObject.setObjectId(id); getGraphManager().registerNode(id, localObject); localObject.setPersistenceState(PersistenceState.HOLLOW); return localObject; } }
// serialization support private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // TODO: most of this should be in the superclass, especially the code // connecting // super transient ivars // read non-transient properties in.defaultReadObject(); // deserialize local snapshots cache if (!isUsingSharedSnapshotCache()) { DataRowStore cache = (DataRowStore) in.readObject(); objectStore.setDataRowCache(cache); } // CayenneDataObjects have a transient DataContext // because at deserialize time the datacontext may need to be different // than the one at serialize time (for programmer defined reasons). // So, when a DataObject is resurrected because it's DataContext was // serialized, it will then set the objects DataContext to the correct // one // If deserialized "otherwise", it will not have a DataContext. synchronized (getObjectStore()) { Iterator<?> it = objectStore.getObjectIterator(); while (it.hasNext()) { Persistent object = (Persistent) it.next(); object.setObjectContext(this); } } // ... deferring initialization of transient properties of this context // till first // access, so that it can attach to Cayenne runtime using appropriate // thread // injector. }