You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Ольга Ткачева <tk...@gmail.com> on 2009/11/18 15:29:07 UTC

Re: svn commit: r881740 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/ main/java/org/apache/cayenne/access/ main/java/org/apache/cayenne/reflect/ main/java/org/apache/cayenne/remote/ test/java/org/apa

Andrey, after your commit I have this problem:

[INFO] Compilation failure
/home/olga/cayenne-git/framework/cayenne-tools/src/test/java/org/apache/cayenne/gen/ClientDataMapGeneratedQueryRunTest.java:[59,86]
incompatible types
found   : java.util.List<org.apache.cayenne.testdo.mt.MtTable1>
required: java.util.List<org.apache.cayenne.testdo.mt.ClientMtTable1>

and reasonable error in cayenne-tools.


2009/11/18 <an...@apache.org>

> Author: andrey
> Date: Wed Nov 18 12:08:20 2009
> New Revision: 881740
>
> URL: http://svn.apache.org/viewvc?rev=881740&view=rev
> Log:
> CAY-1312 Allow lifecycle callbacks on ROP client. Only method invokes, i.e.
> no configuration for those callbacks yet
>
> Added:
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
>      - copied, changed from r881253,
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> Removed:
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextDeleteAction.java
> Modified:
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
>
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> Wed Nov 18 12:08:20 2009
> @@ -33,6 +33,7 @@
>  import org.apache.cayenne.graph.GraphEvent;
>  import org.apache.cayenne.graph.GraphManager;
>  import org.apache.cayenne.map.EntityResolver;
> +import org.apache.cayenne.map.LifecycleEvent;
>  import org.apache.cayenne.map.ObjEntity;
>  import org.apache.cayenne.query.ObjectIdQuery;
>  import org.apache.cayenne.query.Query;
> @@ -103,8 +104,6 @@
>
>     public abstract void commitChangesToParent();
>
> -    public abstract void deleteObject(Object object) throws
> DeleteDenyException;
> -
>     public abstract Collection<?> deletedObjects();
>
>     public DataChannel getChannel() {
> @@ -381,9 +380,24 @@
>     }
>
>     /**
> -     * If ObjEntity qualifier is set, asks it to inject initial value to
> an object
> +     * If ObjEntity qualifier is set, asks it to inject initial value to
> an object.
> +     * Also performs all Persistent initialization operations
>      */
> -    protected void injectInitialValue(Object object) {
> +    protected void injectInitialValue(Object obj) {
> +        // must follow this exact order of property initialization per
> CAY-653, i.e. have
> +        // the id and the context in place BEFORE setPersistence is called
> +
> +        Persistent object = (Persistent) obj;
> +
> +        object.setObjectContext(this);
> +        object.setPersistenceState(PersistenceState.NEW);
> +
> +        GraphManager graphManager = getGraphManager();
> +        synchronized (graphManager) {
> +            graphManager.registerNode(object.getObjectId(), object);
> +            graphManager.nodeCreated(object.getObjectId());
> +        }
> +
>         ObjEntity entity;
>         try {
>             entity =
> getEntityResolver().lookupObjEntity(object.getClass());
> @@ -398,5 +412,37 @@
>                 ((ValueInjector)
> entity.getDeclaredQualifier()).injectValue(object);
>             }
>         }
> +
> +        // invoke callbacks
> +        getEntityResolver().getCallbackRegistry().performCallbacks(
> +                LifecycleEvent.POST_ADD,
> +                object);
> +    }
> +
> +    /**
> +     * Schedules an object for deletion on the next commit of this
> context. Object's
> +     * persistence state is changed to PersistenceState.DELETED; objects
> related to this
> +     * object are processed according to delete rules, i.e. relationships
> can be unset
> +     * ("nullify" rule), deletion operation is cascaded (cascade rule).
> +     *
> +     * @param object a persistent object that we want to delete.
> +     * @throws DeleteDenyException if a DENY delete rule is applicable for
> object
> +     *             deletion.
> +     * @throws NullPointerException if object is null.
> +     */
> +    public void deleteObject(Object object) {
> +        new ObjectContextDeleteAction(this).performDelete((Persistent)
> object);
> +    }
> +
> +    public void deleteObjects(Collection<?> objects) throws
> DeleteDenyException {
> +        if (objects.isEmpty())
> +            return;
> +
> +        // Don't call deleteObject() directly since it would be less
> efficient.
> +        ObjectContextDeleteAction ocda = new
> ObjectContextDeleteAction(this);
> +
> +        // Make a copy to iterate over to avoid
> ConcurrentModificationException.
> +        for (Persistent object : (ArrayList<Persistent>) new
> ArrayList(objects))
> +            ocda.performDelete(object);
>     }
>  }
> \ No newline at end of file
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> Wed Nov 18 12:08:20 2009
> @@ -308,27 +308,6 @@
>     }
>
>     /**
> -     * Deletes an object locally, scheduling it for future deletion from
> the external data
> -     * store.
> -     */
> -    @Override
> -    public void deleteObject(Object object) {
> -        new ObjectContextDeleteAction(this).performDelete((Persistent)
> object);
> -    }
> -
> -    public void deleteObjects(Collection<?> objects) throws
> DeleteDenyException {
> -        if (objects.isEmpty())
> -            return;
> -
> -        // Don't call deleteObject() directly since it would be less
> efficient.
> -        ObjectContextDeleteAction ocda = new
> ObjectContextDeleteAction(this);
> -
> -        // Make a copy to iterate over to avoid
> ConcurrentModificationException.
> -        for (Persistent object : (ArrayList<Persistent>) new
> ArrayList(objects))
> -            ocda.performDelete(object);
> -    }
> -
> -    /**
>      * Creates and registers a new Persistent object instance.
>      */
>     @Override
> @@ -527,16 +506,6 @@
>             object.setObjectId(id);
>         }
>
> -        // must follow this exact order of property initialization per
> CAY-653, i.e. have
> -        // the id and the context in place BEFORE setPersistence is called
> -        object.setObjectContext(this);
> -        object.setPersistenceState(PersistenceState.NEW);
> -
> -        synchronized (graphManager) {
> -            graphManager.registerNode(id, object);
> -            graphManager.nodeCreated(id);
> -        }
> -
>         injectInitialValue(object);
>     }
>
>
> Copied:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
> (from r881253,
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java)
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java&r1=881253&r2=881740&rev=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
> Wed Nov 18 12:08:20 2009
> @@ -16,14 +16,13 @@
>  *  specific language governing permissions and limitations
>  *  under the License.
>  ****************************************************************/
> -package org.apache.cayenne.access;
> +package org.apache.cayenne;
>
>  import java.util.ArrayList;
>  import java.util.Collection;
>  import java.util.HashSet;
>  import java.util.Set;
>
> -import org.apache.cayenne.DataChannel;
>  import org.apache.cayenne.graph.GraphChangeHandler;
>  import org.apache.cayenne.graph.GraphDiff;
>  import org.apache.cayenne.graph.GraphManager;
> @@ -32,10 +31,11 @@
>
>  /**
>  * @since 3.0
> + * note: made public in 3.1 to be used in all tiers
>  */
> -abstract class DataChannelSyncCallbackAction implements GraphChangeHandler
> {
> +public abstract class DataChannelSyncCallbackAction implements
> GraphChangeHandler {
>
> -    static DataChannelSyncCallbackAction getCallbackAction(
> +    public static DataChannelSyncCallbackAction getCallbackAction(
>             LifecycleCallbackRegistry callbackRegistry,
>             GraphManager graphManager,
>             GraphDiff changes,
> @@ -73,9 +73,9 @@
>
>     protected abstract boolean hasListeners();
>
> -    abstract void applyPreCommit();
> +    public abstract void applyPreCommit();
>
> -    abstract void applyPostCommit();
> +    public abstract void applyPostCommit();
>
>     void apply(LifecycleEvent callbackType, Collection<?> objects) {
>         if (seenIds != null && objects != null) {
> @@ -166,13 +166,13 @@
>         }
>
>         @Override
> -        void applyPreCommit() {
> +        public void applyPreCommit() {
>             apply(LifecycleEvent.PRE_PERSIST, persisted);
>             apply(LifecycleEvent.PRE_UPDATE, updated);
>         }
>
>         @Override
> -        void applyPostCommit() {
> +        public void applyPostCommit() {
>             apply(LifecycleEvent.POST_UPDATE, updated);
>             apply(LifecycleEvent.POST_REMOVE, removed);
>             apply(LifecycleEvent.POST_PERSIST, persisted);
> @@ -192,12 +192,12 @@
>         }
>
>         @Override
> -        void applyPreCommit() {
> +        public void applyPreCommit() {
>             // noop
>         }
>
>         @Override
> -        void applyPostCommit() {
> +        public void applyPostCommit() {
>             apply(LifecycleEvent.POST_LOAD, updated);
>             apply(LifecycleEvent.POST_LOAD, removed);
>         }
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> Wed Nov 18 12:08:20 2009
> @@ -23,14 +23,14 @@
>  import java.util.Collection;
>  import java.util.Collections;
>  import java.util.Iterator;
> +import java.util.Map;
>
>  import org.apache.cayenne.map.DeleteRule;
> -import org.apache.cayenne.map.ObjEntity;
> +import org.apache.cayenne.map.LifecycleEvent;
>  import org.apache.cayenne.map.ObjRelationship;
>  import org.apache.cayenne.reflect.ArcProperty;
>  import org.apache.cayenne.reflect.AttributeProperty;
>  import org.apache.cayenne.reflect.ClassDescriptor;
> -import org.apache.cayenne.reflect.Property;
>  import org.apache.cayenne.reflect.PropertyVisitor;
>  import org.apache.cayenne.reflect.ToManyProperty;
>  import org.apache.cayenne.reflect.ToOneProperty;
> @@ -54,6 +54,10 @@
>
>         if (oldState == PersistenceState.TRANSIENT
>                 || oldState == PersistenceState.DELETED) {
> +            // Drop out... especially in case of DELETED we might be about
> to get
> +            // into a horrible recursive loop due to CASCADE delete rules.
> +            // Assume that everything must have been done correctly
> already
> +            // and *don't* do it again
>             return false;
>         }
>
> @@ -69,6 +73,11 @@
>                             + ", context: "
>                             + context);
>         }
> +
> +        // must resolve HOLLOW objects before delete... needed
> +        // to process relationships and optimistic locking...
> +
> +        context.prepareForAccess(object, null, false);
>
>         if (oldState == PersistenceState.NEW) {
>             deleteNew(object);
> @@ -80,133 +89,148 @@
>         return true;
>     }
>
> -    private void deleteNew(Persistent object) {
> +    private void deleteNew(Persistent object) throws DeleteDenyException {
>         object.setPersistenceState(PersistenceState.TRANSIENT);
>         processDeleteRules(object, PersistenceState.NEW);
> +
> +        // if an object was NEW, we must throw it out
>         context.getGraphManager().unregisterNode(object.getObjectId());
>     }
>
> -    private void deletePersistent(Persistent object) {
> +    private void deletePersistent(Persistent object) throws
> DeleteDenyException {
> +
>  context.getEntityResolver().getCallbackRegistry().performCallbacks(
> +                LifecycleEvent.PRE_REMOVE,
> +                object);
> +
>         int oldState = object.getPersistenceState();
>         object.setPersistenceState(PersistenceState.DELETED);
>         processDeleteRules(object, oldState);
>         context.getGraphManager().nodeRemoved(object.getObjectId());
>     }
>
> -    private void processDeleteRules(final Persistent object, final int
> oldState) {
> +    private Collection toCollection(Object object) {
>
> -        String entityName = object.getObjectId().getEntityName();
> -        final ObjEntity entity =
> context.getEntityResolver().getObjEntity(entityName);
> -        ClassDescriptor descriptor =
> context.getEntityResolver().getClassDescriptor(
> -                entityName);
> +        if (object == null) {
> +            return Collections.EMPTY_LIST;
> +        }
>
> -        descriptor.visitProperties(new PropertyVisitor() {
> +        // create copies of collections to avoid iterator exceptions
> +        if (object instanceof Collection) {
> +            return new ArrayList((Collection) object);
> +        }
> +        else if (object instanceof Map) {
> +            return new ArrayList(((Map) object).values());
> +        }
> +        else {
> +            return Collections.singleton(object);
> +        }
> +    }
>
> -            public boolean visitToMany(ToManyProperty property) {
> -                ObjRelationship relationship = (ObjRelationship) entity
> -                        .getRelationship(property.getName());
> +    private void processDeleteRules(final Persistent object, int oldState)
> +            throws DeleteDenyException {
>
> -                processRules(object, property,
> relationship.getDeleteRule(), oldState);
> -                return true;
> -            }
> +        ClassDescriptor descriptor =
> context.getEntityResolver().getClassDescriptor(
> +                object.getObjectId().getEntityName());
>
> -            public boolean visitToOne(ToOneProperty property) {
> -                ObjRelationship relationship = (ObjRelationship) entity
> -                        .getRelationship(property.getName());
> +        for (final ObjRelationship relationship :
> descriptor.getEntity().getRelationships()) {
>
> -                processRules(object, property,
> relationship.getDeleteRule(), oldState);
> -                return true;
> -            }
> +            boolean processFlattened = relationship.isFlattened()
> +                    && relationship.isToDependentEntity()
> +                    && !relationship.isReadOnly();
>
> -            public boolean visitAttribute(AttributeProperty property) {
> -                return true;
> +            // first check for no action... bail out if no flattened
> processing is needed
> +            if (relationship.getDeleteRule() == DeleteRule.NO_ACTION &&
> !processFlattened) {
> +                continue;
>             }
> -        });
> -    }
> -
> -    private void processRules(
> -            Persistent object,
> -            ArcProperty property,
> -            int deleteRule,
> -            int oldState) {
> -
> -        if (deleteRule == DeleteRule.NO_ACTION) {
> -            return;
> -        }
> -
> -        Collection<?> relatedObjects = relatedObjects(object, property);
> -        if (relatedObjects.isEmpty()) {
> -            return;
> -        }
>
> -        switch (deleteRule) {
> +            ArcProperty property = (ArcProperty)
> descriptor.getProperty(relationship
> +                    .getName());
> +            Collection relatedObjects =
> toCollection(property.readProperty(object));
> +
> +            // no related object, bail out
> +            if (relatedObjects.size() == 0) {
> +                continue;
> +            }
>
> -            case DeleteRule.DENY:
> +            // process DENY rule first...
> +            if (relationship.getDeleteRule() == DeleteRule.DENY) {
>                 object.setPersistenceState(oldState);
> +
>                 String message = relatedObjects.size() == 1
>                         ? "1 related object"
>                         : relatedObjects.size() + " related objects";
> -                throw new DeleteDenyException(object, property.getName(),
> message);
> -
> -            case DeleteRule.NULLIFY:
> -                ArcProperty reverseArc =
> property.getComplimentaryReverseArc();
> +                throw new DeleteDenyException(object,
> relationship.getName(), message);
> +            }
>
> -                if (reverseArc != null) {
> +            // process flattened with dependent join tables...
> +            // joins must be removed even if they are non-existent or
> ignored in the
> +            // object graph
> +            if (processFlattened) {
> +                Iterator iterator = relatedObjects.iterator();
> +                while (iterator.hasNext()) {
> +                    Persistent relatedObject = (Persistent)
> iterator.next();
> +
>  context.getGraphManager().arcDeleted(object.getObjectId(), relatedObject
> +                            .getObjectId(), relationship.getName());
> +                }
> +            }
>
> -                    if (reverseArc instanceof ToManyProperty) {
> -                        for (Object relatedObject : relatedObjects) {
> -                            ((ToManyProperty) reverseArc).removeTarget(
> -                                    relatedObject,
> -                                    object,
> -                                    true);
> -                        }
> +            // process remaining rules
> +            switch (relationship.getDeleteRule()) {
> +                case DeleteRule.NO_ACTION:
> +                    break;
> +                case DeleteRule.NULLIFY:
> +                    ArcProperty reverseArc =
> property.getComplimentaryReverseArc();
> +
> +                    if (reverseArc == null) {
> +                        // nothing we can do here
> +                        break;
>                     }
> -                    else {
> -                        for (Object relatedObject : relatedObjects) {
> -                            ((ToOneProperty) reverseArc).setTarget(
> -                                    relatedObject,
> -                                    null,
> -                                    true);
> -                        }
> -                    }
> -                }
>
> -                break;
> -            case DeleteRule.CASCADE:
> +                    final Collection finalRelatedObjects = relatedObjects;
>
> -                Iterator<?> iterator = relatedObjects.iterator();
> -                while (iterator.hasNext()) {
> -                    Persistent relatedObject = (Persistent)
> iterator.next();
> +                    reverseArc.visit(new PropertyVisitor() {
>
> -                    // this action object is stateless, so we can use
> 'performDelete'
> -                    // recursively.
> -                    performDelete(relatedObject);
> -                }
> +                        public boolean visitAttribute(AttributeProperty
> property) {
> +                            return false;
> +                        }
>
> -                break;
> -            default:
> -                object.setPersistenceState(oldState);
> -                throw new CayenneRuntimeException("Invalid delete rule: "
> + deleteRule);
> -        }
> -    }
> +                        public boolean visitToMany(ToManyProperty
> property) {
> +                            Iterator iterator =
> finalRelatedObjects.iterator();
> +                            while (iterator.hasNext()) {
> +                                Object relatedObject = iterator.next();
> +                                property.removeTarget(relatedObject,
> object, true);
> +                            }
>
> -    private Collection<?> relatedObjects(Object object, Property property)
> {
> -        Object related = property.readProperty(object);
> +                            return false;
> +                        }
>
> -        if (related == null) {
> -            return Collections.EMPTY_LIST;
> -        }
> -        // return collections by copy, to allow removal of objects from
> the underlying
> -        // relationship inside the iterator
> -        else if (property instanceof ToManyProperty) {
> -            Collection<?> relatedCollection = (Collection<?>) related;
> -            return relatedCollection.isEmpty()
> -                    ? Collections.EMPTY_LIST
> -                    : new ArrayList<Object>(relatedCollection);
> -        }
> -        // TODO: andrus 11/21/2007 - ToManyMapProperty check
> -        else {
> -            return Collections.singleton(related);
> +                        public boolean visitToOne(ToOneProperty property)
> {
> +                            // Inverse is to-one - find all related
> objects and
> +                            // nullify the reverse relationship
> +                            Iterator iterator =
> finalRelatedObjects.iterator();
> +                            while (iterator.hasNext()) {
> +                                Object relatedObject = iterator.next();
> +                                property.setTarget(relatedObject, null,
> true);
> +                            }
> +                            return false;
> +                        }
> +                    });
> +
> +                    break;
> +                case DeleteRule.CASCADE:
> +                    // Delete all related objects
> +                    Iterator iterator = relatedObjects.iterator();
> +                    while (iterator.hasNext()) {
> +                        Persistent relatedObject = (Persistent)
> iterator.next();
> +                        performDelete(relatedObject);
> +                    }
> +
> +                    break;
> +                default:
> +                    object.setPersistenceState(oldState);
> +                    throw new CayenneRuntimeException("Invalid delete rule
> "
> +                            + relationship.getDeleteRule());
> +            }
>         }
>     }
>  }
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> Wed Nov 18 12:08:20 2009
> @@ -35,7 +35,6 @@
>  import org.apache.cayenne.DataChannel;
>  import org.apache.cayenne.DataObject;
>  import org.apache.cayenne.DataRow;
> -import org.apache.cayenne.DeleteDenyException;
>  import org.apache.cayenne.Fault;
>  import org.apache.cayenne.ObjectContext;
>  import org.apache.cayenne.ObjectId;
> @@ -54,7 +53,6 @@
>  import org.apache.cayenne.map.DbJoin;
>  import org.apache.cayenne.map.DbRelationship;
>  import org.apache.cayenne.map.EntityResolver;
> -import org.apache.cayenne.map.LifecycleEvent;
>  import org.apache.cayenne.map.ObjAttribute;
>  import org.apache.cayenne.map.ObjEntity;
>  import org.apache.cayenne.map.ObjRelationship;
> @@ -629,18 +627,9 @@
>         // note that the order of initialization of persistence artifacts
> below is
>         // important - do not change it lightly
>         object.setObjectId(id);
> -        object.setObjectContext(this);
> -        object.setPersistenceState(PersistenceState.NEW);
> -        getObjectStore().registerNode(id, object);
> -        getObjectStore().nodeCreated(id);
>
>         injectInitialValue(object);
>
> -        // invoke callbacks
> -        getEntityResolver().getCallbackRegistry().performCallbacks(
> -                LifecycleEvent.POST_ADD,
> -                object);
> -
>         return object;
>     }
>
> @@ -684,21 +673,17 @@
>         else {
>             persistent.setObjectId(new ObjectId(entity.getName()));
>         }
> -
> -        persistent.setObjectContext(this);
> -        persistent.setPersistenceState(PersistenceState.NEW);
> -
> -        getObjectStore().registerNode(persistent.getObjectId(), object);
> -        getObjectStore().nodeCreated(persistent.getObjectId());
> -
> -        // now we need to find all arc changes, inject missing value
> holders and pull in
> -        // all transient connected objects
> -
> +
>         ClassDescriptor descriptor =
> getEntityResolver().getClassDescriptor(
>                 entity.getName());
>         if (descriptor == null) {
>             throw new IllegalArgumentException("Invalid entity name: " +
> entity.getName());
>         }
> +
> +        injectInitialValue(object);
> +
> +        // now we need to find all arc changes, inject missing value
> holders and pull in
> +        // all transient connected objects
>
>         descriptor.visitProperties(new PropertyVisitor() {
>
> @@ -752,13 +737,6 @@
>                 return true;
>             }
>         });
> -
> -        injectInitialValue(object);
> -
> -        // invoke callbacks
> -        getEntityResolver().getCallbackRegistry().performCallbacks(
> -                LifecycleEvent.POST_ADD,
> -                persistent);
>     }
>
>     /**
> @@ -773,48 +751,6 @@
>     }
>
>     /**
> -     * Schedules all objects in the collection for deletion on the next
> commit of this
> -     * DataContext. Object's persistence state is changed to
> PersistenceState.DELETED;
> -     * objects related to this object are processed according to delete
> rules, i.e.
> -     * relationships can be unset ("nullify" rule), deletion operation is
> cascaded
> -     * (cascade rule).
> -     * <p>
> -     * <i>"Nullify" delete rule side effect: </i> passing a collection
> representing
> -     * to-many relationship with nullify delete rule may result in objects
> being removed
> -     * from collection.
> -     * </p>
> -     *
> -     * @since 1.2
> -     */
> -    public void deleteObjects(Collection objects) {
> -        if (objects.isEmpty()) {
> -            return;
> -        }
> -
> -        // clone object list... this maybe a relationship collection with
> nullify delete
> -        // rule, so modifying
> -        for (Persistent object : new ArrayList<Persistent>(objects)) {
> -            deleteObject(object);
> -        }
> -    }
> -
> -    /**
> -     * Schedules an object for deletion on the next commit of this
> DataContext. Object's
> -     * persistence state is changed to PersistenceState.DELETED; objects
> related to this
> -     * object are processed according to delete rules, i.e. relationships
> can be unset
> -     * ("nullify" rule), deletion operation is cascaded (cascade rule).
> -     *
> -     * @param object a persistent object that we want to delete.
> -     * @throws DeleteDenyException if a DENY delete rule is applicable for
> object
> -     *             deletion.
> -     * @throws NullPointerException if object is null.
> -     */
> -    @Override
> -    public void deleteObject(Object object) throws DeleteDenyException {
> -        new DataContextDeleteAction(this).performDelete((Persistent)
> object);
> -    }
> -
> -    /**
>      * If the parent channel is a DataContext, reverts local changes to
> make this context
>      * look like the parent, if the parent channel is a DataDomain, reverts
> all changes.
>      *
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> Wed Nov 18 12:08:20 2009
> @@ -28,6 +28,7 @@
>
>  import org.apache.cayenne.CayenneRuntimeException;
>  import org.apache.cayenne.DataChannel;
> +import org.apache.cayenne.DataChannelSyncCallbackAction;
>  import org.apache.cayenne.ObjectContext;
>  import org.apache.cayenne.QueryResponse;
>  import org.apache.cayenne.access.jdbc.BatchQueryBuilderFactory;
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> Wed Nov 18 12:08:20 2009
> @@ -99,6 +99,7 @@
>      */
>     public void addListener(Class<?> entityClass, LifecycleListener
> listener) {
>         addListener(LifecycleEvent.POST_ADD, entityClass, listener,
> "postAdd");
> +        addListener(LifecycleEvent.POST_PERSIST, entityClass, listener,
> "prePersist");
>         addListener(LifecycleEvent.POST_PERSIST, entityClass, listener,
> "postPersist");
>         addListener(LifecycleEvent.PRE_REMOVE, entityClass, listener,
> "preRemove");
>         addListener(LifecycleEvent.POST_REMOVE, entityClass, listener,
> "postRemove");
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> Wed Nov 18 12:08:20 2009
> @@ -24,6 +24,7 @@
>
>  import org.apache.cayenne.CayenneRuntimeException;
>  import org.apache.cayenne.DataChannel;
> +import org.apache.cayenne.DataChannelSyncCallbackAction;
>  import org.apache.cayenne.ObjectContext;
>  import org.apache.cayenne.ObjectId;
>  import org.apache.cayenne.Persistent;
> @@ -169,6 +170,14 @@
>             ObjectContext originatingContext,
>             GraphDiff changes,
>             int syncType) {
> +
> +        DataChannelSyncCallbackAction callbackAction =
> DataChannelSyncCallbackAction
> +            .getCallbackAction(
> +                getEntityResolver().getCallbackRegistry(),
> +                originatingContext.getGraphManager(),
> +                changes,
> +                syncType);
> +        callbackAction.applyPreCommit();
>
>         changes = diffCompressor.compress(changes);
>
> @@ -221,6 +230,7 @@
>             }
>         }
>
> +        callbackAction.applyPostCommit();
>         return replyDiff;
>     }
>
>
> Added:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java?rev=881740&view=auto
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> (added)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> Wed Nov 18 12:08:20 2009
> @@ -0,0 +1,114 @@
> +/*****************************************************************
> + *   Licensed to the Apache Software Foundation (ASF) under one
> + *  or more contributor license agreements.  See the NOTICE file
> + *  distributed with this work for additional information
> + *  regarding copyright ownership.  The ASF licenses this file
> + *  to you under the Apache License, Version 2.0 (the
> + *  "License"); you may not use this file except in compliance
> + *  with the License.  You may obtain a copy of the License at
> + *
> + *    http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing,
> + *  software distributed under the License is distributed on an
> + *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + *  KIND, either express or implied.  See the License for the
> + *  specific language governing permissions and limitations
> + *  under the License.
> + ****************************************************************/
> +package org.apache.cayenne.remote;
> +
> +import org.apache.cayenne.LifecycleListener;
> +import org.apache.cayenne.ObjectContext;
> +import org.apache.cayenne.testdo.mt.ClientMtLifecycles;
> +
> +public class RemoteCallbacksTest extends RemoteCayenneCase implements
> LifecycleListener {
> +    private int added, loaded, prePersisted, postPersisted, preRemoved,
> postRemoved, preUpdated, postUpdated;
> +
> +    @Override
> +    public void setUp() throws Exception {
> +        super.setUp();
> +        added = 0;
> +        loaded = 0;
> +        prePersisted = 0;
> +        postPersisted = 0;
> +        preRemoved = 0;
> +        postRemoved = 0;
> +        preUpdated = 0;
> +        postUpdated = 0;
> +    }
> +
> +    public void testDefault() throws InterruptedException {
> +        ObjectContext context = createROPContext();
> +
>  context.getEntityResolver().getCallbackRegistry().addListener(ClientMtLifecycles.class,
> this);
> +
> +        assertAll(0, 0, 0, 0, 0, 0, 0, 0);
> +        ClientMtLifecycles l1 =
> context.newObject(ClientMtLifecycles.class);
> +
> +        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
> +        l1.setName("x");
> +        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
> +
> +        context.commitChanges();
> +        Thread.sleep(5); //until commit
> +        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
> +
> +        l1.setName("x2");
> +        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
> +
> +        context.commitChanges();
> +        Thread.sleep(5); //until commit
> +        assertAll(1, 0, 1, 1, 1, 1, 0, 0);
> +
> +        context.deleteObject(l1);
> +        assertAll(1, 0, 1, 1, 1, 1, 1, 0);
> +
> +        context.commitChanges();
> +        Thread.sleep(5); //until commit
> +        assertAll(1, 0, 1, 1, 1, 1, 1, 1);
> +    }
> +
> +    private void assertAll(int added, int loaded, int prePersisted, int
> postPersisted,
> +            int preUpdated, int postUpdated, int preRemoved, int
> postRemoved) {
> +        assertEquals(this.added, added);
> +        assertEquals(this.loaded, loaded);
> +        assertEquals(this.prePersisted, prePersisted);
> +        assertEquals(this.postPersisted, postPersisted);
> +        assertEquals(this.preRemoved, preRemoved);
> +        assertEquals(this.postRemoved, postRemoved);
> +        assertEquals(this.preUpdated, preUpdated);
> +        assertEquals(this.postUpdated, postUpdated);
> +    }
> +
> +    public void postAdd(Object entity) {
> +        added++;
> +    }
> +
> +    public void postLoad(Object entity) {
> +        loaded++;
> +    }
> +
> +    public void postPersist(Object entity) {
> +        postPersisted++;
> +    }
> +
> +    public void postRemove(Object entity) {
> +        postRemoved++;
> +    }
> +
> +    public void postUpdate(Object entity) {
> +        postUpdated++;
> +    }
> +
> +    public void prePersist(Object entity) {
> +        prePersisted++;
> +    }
> +
> +    public void preRemove(Object entity) {
> +        preRemoved++;
> +    }
> +
> +    public void preUpdate(Object entity) {
> +        preUpdated++;
> +    }
> +}
>
> Added:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java?rev=881740&view=auto
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> (added)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> Wed Nov 18 12:08:20 2009
> @@ -0,0 +1,10 @@
> +package org.apache.cayenne.testdo.mt;
> +
> +import org.apache.cayenne.testdo.mt.auto._ClientMtLifecycles;
> +
> +/**
> + * A persistent class mapped as "MtLifecycles" Cayenne entity.
> + */
> +public class ClientMtLifecycles extends _ClientMtLifecycles {
> +
> +}
>
> Added:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java?rev=881740&view=auto
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> (added)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> Wed Nov 18 12:08:20 2009
> @@ -0,0 +1,7 @@
> +package org.apache.cayenne.testdo.mt;
> +
> +import org.apache.cayenne.testdo.mt.auto._MtLifecycles;
> +
> +public class MtLifecycles extends _MtLifecycles {
> +
> +}
>
> Added:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java?rev=881740&view=auto
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> (added)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> Wed Nov 18 12:08:20 2009
> @@ -0,0 +1,37 @@
> +package org.apache.cayenne.testdo.mt.auto;
> +
> +import org.apache.cayenne.PersistentObject;
> +
> +/**
> + * A generated persistent class mapped as "MtLifecycles" Cayenne entity.
> It is a good idea to
> + * avoid changing this class manually, since it will be overwritten next
> time code is
> + * regenerated. If you need to make any customizations, put them in a
> subclass.
> + */
> +public abstract class _ClientMtLifecycles extends PersistentObject {
> +
> +    public static final String NAME_PROPERTY = "name";
> +
> +    protected String name;
> +
> +    public String getName() {
> +        if(objectContext != null) {
> +            objectContext.prepareForAccess(this, "name", false);
> +        }
> +
> +        return name;
> +    }
> +    public void setName(String name) {
> +        if(objectContext != null) {
> +            objectContext.prepareForAccess(this, "name", false);
> +        }
> +
> +        Object oldValue = this.name;
> +        this.name = name;
> +
> +        // notify objectContext about simple property change
> +        if(objectContext != null) {
> +            objectContext.propertyChanged(this, "name", oldValue, name);
> +        }
> +    }
> +
> +}
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> Wed Nov 18 12:08:20 2009
> @@ -5,7 +5,7 @@
>  import org.apache.cayenne.ObjectContext;
>  import org.apache.cayenne.PersistentObject;
>  import org.apache.cayenne.query.NamedQuery;
> -import org.apache.cayenne.testdo.mt.ClientMtTable1;
> +import org.apache.cayenne.testdo.mt.MtTable1;
>
>  /**
>  * This class was generated by Cayenne.
> @@ -15,15 +15,21 @@
>  */
>  public class _ClientMultiTier {
>
> -    public List<ClientMtTable1> performAllMtTable1(ObjectContext context )
> {
> +    public static final String ALL_MT_TABLE1_QUERYNAME = "AllMtTable1";
> +
> +    public static final String MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> "MtQueryWithLocalCache";
> +
> +    public static final String
> PARAMETERIZED_MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> "ParameterizedMtQueryWithLocalCache";
> +
> +    public List<MtTable1> performAllMtTable1(ObjectContext context ) {
>         return context.performQuery(new NamedQuery("AllMtTable1"));
>     }
>
> -    public List<ClientMtTable1> performMtQueryWithLocalCache(ObjectContext
> context ) {
> +    public List<MtTable1> performMtQueryWithLocalCache(ObjectContext
> context ) {
>         return context.performQuery(new
> NamedQuery("MtQueryWithLocalCache"));
>     }
>
> -    public List<ClientMtTable1>
> performParameterizedMtQueryWithLocalCache(ObjectContext context , String g)
> {
> +    public List<MtTable1>
> performParameterizedMtQueryWithLocalCache(ObjectContext context , String g)
> {
>         String[] parameters = {
>             "g",
>         };
>
> Added:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java?rev=881740&view=auto
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> (added)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> Wed Nov 18 12:08:20 2009
> @@ -0,0 +1,23 @@
> +package org.apache.cayenne.testdo.mt.auto;
> +
> +import org.apache.cayenne.CayenneDataObject;
> +
> +/**
> + * Class _MtLifecycles was generated by Cayenne.
> + * It is probably a good idea to avoid changing this class manually,
> + * since it may be overwritten next time code is regenerated.
> + * If you need to make any customizations, please use subclass.
> + */
> +public abstract class _MtLifecycles extends CayenneDataObject {
> +
> +    public static final String NAME_PROPERTY = "name";
> +
> +
> +    public void setName(String name) {
> +        writeProperty("name", name);
> +    }
> +    public String getName() {
> +        return (String)readProperty("name");
> +    }
> +
> +}
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> Wed Nov 18 12:08:20 2009
> @@ -14,6 +14,12 @@
>  */
>  public class _MultiTier {
>
> +    public static final String ALL_MT_TABLE1_QUERYNAME = "AllMtTable1";
> +
> +    public static final String MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> "MtQueryWithLocalCache";
> +
> +    public static final String
> PARAMETERIZED_MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> "ParameterizedMtQueryWithLocalCache";
> +
>     public List<MtTable1> performAllMtTable1(ObjectContext context ) {
>         return context.performQuery(new NamedQuery("AllMtTable1"));
>     }
>
> Modified:
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> URL:
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml?rev=881740&r1=881739&r2=881740&view=diff
>
> ==============================================================================
> ---
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> (original)
> +++
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> Wed Nov 18 12:08:20 2009
> @@ -29,6 +29,10 @@
>                <db-attribute name="TABLE4_ID" type="INTEGER"
> isPrimaryKey="true" isMandatory="true"/>
>                <db-attribute name="TABLE5_ID" type="INTEGER"
> isPrimaryKey="true" isMandatory="true"/>
>        </db-entity>
> +       <db-entity name="MT_LIFECYCLES">
> +               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true"
> isMandatory="true"/>
> +               <db-attribute name="NAME" type="VARCHAR" isMandatory="true"
> length="100"/>
> +       </db-entity>
>        <db-entity name="MT_MAP_TO_MANY">
>                <db-attribute name="ID" type="INTEGER" isPrimaryKey="true"
> isMandatory="true"/>
>        </db-entity>
> @@ -91,6 +95,9 @@
>        <obj-entity name="MtDeleteRule"
> className="org.apache.cayenne.testdo.mt.MtDeleteRule"
> clientClassName="org.apache.cayenne.testdo.mt.ClientMtDeleteRule"
> dbEntityName="MT_DELETE_RULE">
>                <obj-attribute name="name" type="java.lang.String"
> db-attribute-path="NAME"/>
>        </obj-entity>
> +       <obj-entity name="MtLifecycles"
> className="org.apache.cayenne.testdo.mt.MtLifecycles"
> clientClassName="org.apache.cayenne.testdo.mt.ClientMtLifecycles"
> dbEntityName="MT_LIFECYCLES">
> +               <obj-attribute name="name" type="java.lang.String"
> db-attribute-path="NAME"/>
> +       </obj-entity>
>        <obj-entity name="MtMapToMany"
> className="org.apache.cayenne.testdo.mt.MtMapToMany"
> clientClassName="org.apache.cayenne.testdo.mt.ClientMtMapToMany"
> dbEntityName="MT_MAP_TO_MANY">
>        </obj-entity>
>        <obj-entity name="MtMapToManyTarget"
> className="org.apache.cayenne.testdo.mt.MtMapToManyTarget"
> clientClassName="org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget"
> dbEntityName="MT_MAP_TO_MANY_TARGET">
>
>
>


-- 
Olga Tkacheva

Re: svn commit: r881740 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/ main/java/org/apache/cayenne/access/ main/java/org/apache/cayenne/reflect/ main/java/org/apache/cayenne/remote/ test/java/org/apa

Posted by Andrey Razumovsky <ra...@gmail.com>.
Sorry for that. Missed to check that module.
Actually what caused the error is breakage in code generation. Need to check
it first..

2009/11/18 Ольга Ткачева <tk...@gmail.com>

> Andrey, after your commit I have this problem:
>
> [INFO] Compilation failure
>
> /home/olga/cayenne-git/framework/cayenne-tools/src/test/java/org/apache/cayenne/gen/ClientDataMapGeneratedQueryRunTest.java:[59,86]
> incompatible types
> found   : java.util.List<org.apache.cayenne.testdo.mt.MtTable1>
> required: java.util.List<org.apache.cayenne.testdo.mt.ClientMtTable1>
>
> and reasonable error in cayenne-tools.
>
>
> 2009/11/18 <an...@apache.org>
>
> > Author: andrey
> > Date: Wed Nov 18 12:08:20 2009
> > New Revision: 881740
> >
> > URL: http://svn.apache.org/viewvc?rev=881740&view=rev
> > Log:
> > CAY-1312 Allow lifecycle callbacks on ROP client. Only method invokes,
> i.e.
> > no configuration for those callbacks yet
> >
> > Added:
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
> >      - copied, changed from r881253,
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> > Removed:
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextDeleteAction.java
> > Modified:
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> >
> >
>  cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> > Wed Nov 18 12:08:20 2009
> > @@ -33,6 +33,7 @@
> >  import org.apache.cayenne.graph.GraphEvent;
> >  import org.apache.cayenne.graph.GraphManager;
> >  import org.apache.cayenne.map.EntityResolver;
> > +import org.apache.cayenne.map.LifecycleEvent;
> >  import org.apache.cayenne.map.ObjEntity;
> >  import org.apache.cayenne.query.ObjectIdQuery;
> >  import org.apache.cayenne.query.Query;
> > @@ -103,8 +104,6 @@
> >
> >     public abstract void commitChangesToParent();
> >
> > -    public abstract void deleteObject(Object object) throws
> > DeleteDenyException;
> > -
> >     public abstract Collection<?> deletedObjects();
> >
> >     public DataChannel getChannel() {
> > @@ -381,9 +380,24 @@
> >     }
> >
> >     /**
> > -     * If ObjEntity qualifier is set, asks it to inject initial value to
> > an object
> > +     * If ObjEntity qualifier is set, asks it to inject initial value to
> > an object.
> > +     * Also performs all Persistent initialization operations
> >      */
> > -    protected void injectInitialValue(Object object) {
> > +    protected void injectInitialValue(Object obj) {
> > +        // must follow this exact order of property initialization per
> > CAY-653, i.e. have
> > +        // the id and the context in place BEFORE setPersistence is
> called
> > +
> > +        Persistent object = (Persistent) obj;
> > +
> > +        object.setObjectContext(this);
> > +        object.setPersistenceState(PersistenceState.NEW);
> > +
> > +        GraphManager graphManager = getGraphManager();
> > +        synchronized (graphManager) {
> > +            graphManager.registerNode(object.getObjectId(), object);
> > +            graphManager.nodeCreated(object.getObjectId());
> > +        }
> > +
> >         ObjEntity entity;
> >         try {
> >             entity =
> > getEntityResolver().lookupObjEntity(object.getClass());
> > @@ -398,5 +412,37 @@
> >                 ((ValueInjector)
> > entity.getDeclaredQualifier()).injectValue(object);
> >             }
> >         }
> > +
> > +        // invoke callbacks
> > +        getEntityResolver().getCallbackRegistry().performCallbacks(
> > +                LifecycleEvent.POST_ADD,
> > +                object);
> > +    }
> > +
> > +    /**
> > +     * Schedules an object for deletion on the next commit of this
> > context. Object's
> > +     * persistence state is changed to PersistenceState.DELETED; objects
> > related to this
> > +     * object are processed according to delete rules, i.e.
> relationships
> > can be unset
> > +     * ("nullify" rule), deletion operation is cascaded (cascade rule).
> > +     *
> > +     * @param object a persistent object that we want to delete.
> > +     * @throws DeleteDenyException if a DENY delete rule is applicable
> for
> > object
> > +     *             deletion.
> > +     * @throws NullPointerException if object is null.
> > +     */
> > +    public void deleteObject(Object object) {
> > +        new ObjectContextDeleteAction(this).performDelete((Persistent)
> > object);
> > +    }
> > +
> > +    public void deleteObjects(Collection<?> objects) throws
> > DeleteDenyException {
> > +        if (objects.isEmpty())
> > +            return;
> > +
> > +        // Don't call deleteObject() directly since it would be less
> > efficient.
> > +        ObjectContextDeleteAction ocda = new
> > ObjectContextDeleteAction(this);
> > +
> > +        // Make a copy to iterate over to avoid
> > ConcurrentModificationException.
> > +        for (Persistent object : (ArrayList<Persistent>) new
> > ArrayList(objects))
> > +            ocda.performDelete(object);
> >     }
> >  }
> > \ No newline at end of file
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
> > Wed Nov 18 12:08:20 2009
> > @@ -308,27 +308,6 @@
> >     }
> >
> >     /**
> > -     * Deletes an object locally, scheduling it for future deletion from
> > the external data
> > -     * store.
> > -     */
> > -    @Override
> > -    public void deleteObject(Object object) {
> > -        new ObjectContextDeleteAction(this).performDelete((Persistent)
> > object);
> > -    }
> > -
> > -    public void deleteObjects(Collection<?> objects) throws
> > DeleteDenyException {
> > -        if (objects.isEmpty())
> > -            return;
> > -
> > -        // Don't call deleteObject() directly since it would be less
> > efficient.
> > -        ObjectContextDeleteAction ocda = new
> > ObjectContextDeleteAction(this);
> > -
> > -        // Make a copy to iterate over to avoid
> > ConcurrentModificationException.
> > -        for (Persistent object : (ArrayList<Persistent>) new
> > ArrayList(objects))
> > -            ocda.performDelete(object);
> > -    }
> > -
> > -    /**
> >      * Creates and registers a new Persistent object instance.
> >      */
> >     @Override
> > @@ -527,16 +506,6 @@
> >             object.setObjectId(id);
> >         }
> >
> > -        // must follow this exact order of property initialization per
> > CAY-653, i.e. have
> > -        // the id and the context in place BEFORE setPersistence is
> called
> > -        object.setObjectContext(this);
> > -        object.setPersistenceState(PersistenceState.NEW);
> > -
> > -        synchronized (graphManager) {
> > -            graphManager.registerNode(id, object);
> > -            graphManager.nodeCreated(id);
> > -        }
> > -
> >         injectInitialValue(object);
> >     }
> >
> >
> > Copied:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
> > (from r881253,
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java)
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java&r1=881253&r2=881740&rev=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataChannelSyncCallbackAction.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannelSyncCallbackAction.java
> > Wed Nov 18 12:08:20 2009
> > @@ -16,14 +16,13 @@
> >  *  specific language governing permissions and limitations
> >  *  under the License.
> >  ****************************************************************/
> > -package org.apache.cayenne.access;
> > +package org.apache.cayenne;
> >
> >  import java.util.ArrayList;
> >  import java.util.Collection;
> >  import java.util.HashSet;
> >  import java.util.Set;
> >
> > -import org.apache.cayenne.DataChannel;
> >  import org.apache.cayenne.graph.GraphChangeHandler;
> >  import org.apache.cayenne.graph.GraphDiff;
> >  import org.apache.cayenne.graph.GraphManager;
> > @@ -32,10 +31,11 @@
> >
> >  /**
> >  * @since 3.0
> > + * note: made public in 3.1 to be used in all tiers
> >  */
> > -abstract class DataChannelSyncCallbackAction implements
> GraphChangeHandler
> > {
> > +public abstract class DataChannelSyncCallbackAction implements
> > GraphChangeHandler {
> >
> > -    static DataChannelSyncCallbackAction getCallbackAction(
> > +    public static DataChannelSyncCallbackAction getCallbackAction(
> >             LifecycleCallbackRegistry callbackRegistry,
> >             GraphManager graphManager,
> >             GraphDiff changes,
> > @@ -73,9 +73,9 @@
> >
> >     protected abstract boolean hasListeners();
> >
> > -    abstract void applyPreCommit();
> > +    public abstract void applyPreCommit();
> >
> > -    abstract void applyPostCommit();
> > +    public abstract void applyPostCommit();
> >
> >     void apply(LifecycleEvent callbackType, Collection<?> objects) {
> >         if (seenIds != null && objects != null) {
> > @@ -166,13 +166,13 @@
> >         }
> >
> >         @Override
> > -        void applyPreCommit() {
> > +        public void applyPreCommit() {
> >             apply(LifecycleEvent.PRE_PERSIST, persisted);
> >             apply(LifecycleEvent.PRE_UPDATE, updated);
> >         }
> >
> >         @Override
> > -        void applyPostCommit() {
> > +        public void applyPostCommit() {
> >             apply(LifecycleEvent.POST_UPDATE, updated);
> >             apply(LifecycleEvent.POST_REMOVE, removed);
> >             apply(LifecycleEvent.POST_PERSIST, persisted);
> > @@ -192,12 +192,12 @@
> >         }
> >
> >         @Override
> > -        void applyPreCommit() {
> > +        public void applyPreCommit() {
> >             // noop
> >         }
> >
> >         @Override
> > -        void applyPostCommit() {
> > +        public void applyPostCommit() {
> >             apply(LifecycleEvent.POST_LOAD, updated);
> >             apply(LifecycleEvent.POST_LOAD, removed);
> >         }
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextDeleteAction.java
> > Wed Nov 18 12:08:20 2009
> > @@ -23,14 +23,14 @@
> >  import java.util.Collection;
> >  import java.util.Collections;
> >  import java.util.Iterator;
> > +import java.util.Map;
> >
> >  import org.apache.cayenne.map.DeleteRule;
> > -import org.apache.cayenne.map.ObjEntity;
> > +import org.apache.cayenne.map.LifecycleEvent;
> >  import org.apache.cayenne.map.ObjRelationship;
> >  import org.apache.cayenne.reflect.ArcProperty;
> >  import org.apache.cayenne.reflect.AttributeProperty;
> >  import org.apache.cayenne.reflect.ClassDescriptor;
> > -import org.apache.cayenne.reflect.Property;
> >  import org.apache.cayenne.reflect.PropertyVisitor;
> >  import org.apache.cayenne.reflect.ToManyProperty;
> >  import org.apache.cayenne.reflect.ToOneProperty;
> > @@ -54,6 +54,10 @@
> >
> >         if (oldState == PersistenceState.TRANSIENT
> >                 || oldState == PersistenceState.DELETED) {
> > +            // Drop out... especially in case of DELETED we might be
> about
> > to get
> > +            // into a horrible recursive loop due to CASCADE delete
> rules.
> > +            // Assume that everything must have been done correctly
> > already
> > +            // and *don't* do it again
> >             return false;
> >         }
> >
> > @@ -69,6 +73,11 @@
> >                             + ", context: "
> >                             + context);
> >         }
> > +
> > +        // must resolve HOLLOW objects before delete... needed
> > +        // to process relationships and optimistic locking...
> > +
> > +        context.prepareForAccess(object, null, false);
> >
> >         if (oldState == PersistenceState.NEW) {
> >             deleteNew(object);
> > @@ -80,133 +89,148 @@
> >         return true;
> >     }
> >
> > -    private void deleteNew(Persistent object) {
> > +    private void deleteNew(Persistent object) throws DeleteDenyException
> {
> >         object.setPersistenceState(PersistenceState.TRANSIENT);
> >         processDeleteRules(object, PersistenceState.NEW);
> > +
> > +        // if an object was NEW, we must throw it out
> >         context.getGraphManager().unregisterNode(object.getObjectId());
> >     }
> >
> > -    private void deletePersistent(Persistent object) {
> > +    private void deletePersistent(Persistent object) throws
> > DeleteDenyException {
> > +
> >  context.getEntityResolver().getCallbackRegistry().performCallbacks(
> > +                LifecycleEvent.PRE_REMOVE,
> > +                object);
> > +
> >         int oldState = object.getPersistenceState();
> >         object.setPersistenceState(PersistenceState.DELETED);
> >         processDeleteRules(object, oldState);
> >         context.getGraphManager().nodeRemoved(object.getObjectId());
> >     }
> >
> > -    private void processDeleteRules(final Persistent object, final int
> > oldState) {
> > +    private Collection toCollection(Object object) {
> >
> > -        String entityName = object.getObjectId().getEntityName();
> > -        final ObjEntity entity =
> > context.getEntityResolver().getObjEntity(entityName);
> > -        ClassDescriptor descriptor =
> > context.getEntityResolver().getClassDescriptor(
> > -                entityName);
> > +        if (object == null) {
> > +            return Collections.EMPTY_LIST;
> > +        }
> >
> > -        descriptor.visitProperties(new PropertyVisitor() {
> > +        // create copies of collections to avoid iterator exceptions
> > +        if (object instanceof Collection) {
> > +            return new ArrayList((Collection) object);
> > +        }
> > +        else if (object instanceof Map) {
> > +            return new ArrayList(((Map) object).values());
> > +        }
> > +        else {
> > +            return Collections.singleton(object);
> > +        }
> > +    }
> >
> > -            public boolean visitToMany(ToManyProperty property) {
> > -                ObjRelationship relationship = (ObjRelationship) entity
> > -                        .getRelationship(property.getName());
> > +    private void processDeleteRules(final Persistent object, int
> oldState)
> > +            throws DeleteDenyException {
> >
> > -                processRules(object, property,
> > relationship.getDeleteRule(), oldState);
> > -                return true;
> > -            }
> > +        ClassDescriptor descriptor =
> > context.getEntityResolver().getClassDescriptor(
> > +                object.getObjectId().getEntityName());
> >
> > -            public boolean visitToOne(ToOneProperty property) {
> > -                ObjRelationship relationship = (ObjRelationship) entity
> > -                        .getRelationship(property.getName());
> > +        for (final ObjRelationship relationship :
> > descriptor.getEntity().getRelationships()) {
> >
> > -                processRules(object, property,
> > relationship.getDeleteRule(), oldState);
> > -                return true;
> > -            }
> > +            boolean processFlattened = relationship.isFlattened()
> > +                    && relationship.isToDependentEntity()
> > +                    && !relationship.isReadOnly();
> >
> > -            public boolean visitAttribute(AttributeProperty property) {
> > -                return true;
> > +            // first check for no action... bail out if no flattened
> > processing is needed
> > +            if (relationship.getDeleteRule() == DeleteRule.NO_ACTION &&
> > !processFlattened) {
> > +                continue;
> >             }
> > -        });
> > -    }
> > -
> > -    private void processRules(
> > -            Persistent object,
> > -            ArcProperty property,
> > -            int deleteRule,
> > -            int oldState) {
> > -
> > -        if (deleteRule == DeleteRule.NO_ACTION) {
> > -            return;
> > -        }
> > -
> > -        Collection<?> relatedObjects = relatedObjects(object, property);
> > -        if (relatedObjects.isEmpty()) {
> > -            return;
> > -        }
> >
> > -        switch (deleteRule) {
> > +            ArcProperty property = (ArcProperty)
> > descriptor.getProperty(relationship
> > +                    .getName());
> > +            Collection relatedObjects =
> > toCollection(property.readProperty(object));
> > +
> > +            // no related object, bail out
> > +            if (relatedObjects.size() == 0) {
> > +                continue;
> > +            }
> >
> > -            case DeleteRule.DENY:
> > +            // process DENY rule first...
> > +            if (relationship.getDeleteRule() == DeleteRule.DENY) {
> >                 object.setPersistenceState(oldState);
> > +
> >                 String message = relatedObjects.size() == 1
> >                         ? "1 related object"
> >                         : relatedObjects.size() + " related objects";
> > -                throw new DeleteDenyException(object,
> property.getName(),
> > message);
> > -
> > -            case DeleteRule.NULLIFY:
> > -                ArcProperty reverseArc =
> > property.getComplimentaryReverseArc();
> > +                throw new DeleteDenyException(object,
> > relationship.getName(), message);
> > +            }
> >
> > -                if (reverseArc != null) {
> > +            // process flattened with dependent join tables...
> > +            // joins must be removed even if they are non-existent or
> > ignored in the
> > +            // object graph
> > +            if (processFlattened) {
> > +                Iterator iterator = relatedObjects.iterator();
> > +                while (iterator.hasNext()) {
> > +                    Persistent relatedObject = (Persistent)
> > iterator.next();
> > +
> >  context.getGraphManager().arcDeleted(object.getObjectId(), relatedObject
> > +                            .getObjectId(), relationship.getName());
> > +                }
> > +            }
> >
> > -                    if (reverseArc instanceof ToManyProperty) {
> > -                        for (Object relatedObject : relatedObjects) {
> > -                            ((ToManyProperty) reverseArc).removeTarget(
> > -                                    relatedObject,
> > -                                    object,
> > -                                    true);
> > -                        }
> > +            // process remaining rules
> > +            switch (relationship.getDeleteRule()) {
> > +                case DeleteRule.NO_ACTION:
> > +                    break;
> > +                case DeleteRule.NULLIFY:
> > +                    ArcProperty reverseArc =
> > property.getComplimentaryReverseArc();
> > +
> > +                    if (reverseArc == null) {
> > +                        // nothing we can do here
> > +                        break;
> >                     }
> > -                    else {
> > -                        for (Object relatedObject : relatedObjects) {
> > -                            ((ToOneProperty) reverseArc).setTarget(
> > -                                    relatedObject,
> > -                                    null,
> > -                                    true);
> > -                        }
> > -                    }
> > -                }
> >
> > -                break;
> > -            case DeleteRule.CASCADE:
> > +                    final Collection finalRelatedObjects =
> relatedObjects;
> >
> > -                Iterator<?> iterator = relatedObjects.iterator();
> > -                while (iterator.hasNext()) {
> > -                    Persistent relatedObject = (Persistent)
> > iterator.next();
> > +                    reverseArc.visit(new PropertyVisitor() {
> >
> > -                    // this action object is stateless, so we can use
> > 'performDelete'
> > -                    // recursively.
> > -                    performDelete(relatedObject);
> > -                }
> > +                        public boolean visitAttribute(AttributeProperty
> > property) {
> > +                            return false;
> > +                        }
> >
> > -                break;
> > -            default:
> > -                object.setPersistenceState(oldState);
> > -                throw new CayenneRuntimeException("Invalid delete rule:
> "
> > + deleteRule);
> > -        }
> > -    }
> > +                        public boolean visitToMany(ToManyProperty
> > property) {
> > +                            Iterator iterator =
> > finalRelatedObjects.iterator();
> > +                            while (iterator.hasNext()) {
> > +                                Object relatedObject = iterator.next();
> > +                                property.removeTarget(relatedObject,
> > object, true);
> > +                            }
> >
> > -    private Collection<?> relatedObjects(Object object, Property
> property)
> > {
> > -        Object related = property.readProperty(object);
> > +                            return false;
> > +                        }
> >
> > -        if (related == null) {
> > -            return Collections.EMPTY_LIST;
> > -        }
> > -        // return collections by copy, to allow removal of objects from
> > the underlying
> > -        // relationship inside the iterator
> > -        else if (property instanceof ToManyProperty) {
> > -            Collection<?> relatedCollection = (Collection<?>) related;
> > -            return relatedCollection.isEmpty()
> > -                    ? Collections.EMPTY_LIST
> > -                    : new ArrayList<Object>(relatedCollection);
> > -        }
> > -        // TODO: andrus 11/21/2007 - ToManyMapProperty check
> > -        else {
> > -            return Collections.singleton(related);
> > +                        public boolean visitToOne(ToOneProperty
> property)
> > {
> > +                            // Inverse is to-one - find all related
> > objects and
> > +                            // nullify the reverse relationship
> > +                            Iterator iterator =
> > finalRelatedObjects.iterator();
> > +                            while (iterator.hasNext()) {
> > +                                Object relatedObject = iterator.next();
> > +                                property.setTarget(relatedObject, null,
> > true);
> > +                            }
> > +                            return false;
> > +                        }
> > +                    });
> > +
> > +                    break;
> > +                case DeleteRule.CASCADE:
> > +                    // Delete all related objects
> > +                    Iterator iterator = relatedObjects.iterator();
> > +                    while (iterator.hasNext()) {
> > +                        Persistent relatedObject = (Persistent)
> > iterator.next();
> > +                        performDelete(relatedObject);
> > +                    }
> > +
> > +                    break;
> > +                default:
> > +                    object.setPersistenceState(oldState);
> > +                    throw new CayenneRuntimeException("Invalid delete
> rule
> > "
> > +                            + relationship.getDeleteRule());
> > +            }
> >         }
> >     }
> >  }
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> > Wed Nov 18 12:08:20 2009
> > @@ -35,7 +35,6 @@
> >  import org.apache.cayenne.DataChannel;
> >  import org.apache.cayenne.DataObject;
> >  import org.apache.cayenne.DataRow;
> > -import org.apache.cayenne.DeleteDenyException;
> >  import org.apache.cayenne.Fault;
> >  import org.apache.cayenne.ObjectContext;
> >  import org.apache.cayenne.ObjectId;
> > @@ -54,7 +53,6 @@
> >  import org.apache.cayenne.map.DbJoin;
> >  import org.apache.cayenne.map.DbRelationship;
> >  import org.apache.cayenne.map.EntityResolver;
> > -import org.apache.cayenne.map.LifecycleEvent;
> >  import org.apache.cayenne.map.ObjAttribute;
> >  import org.apache.cayenne.map.ObjEntity;
> >  import org.apache.cayenne.map.ObjRelationship;
> > @@ -629,18 +627,9 @@
> >         // note that the order of initialization of persistence artifacts
> > below is
> >         // important - do not change it lightly
> >         object.setObjectId(id);
> > -        object.setObjectContext(this);
> > -        object.setPersistenceState(PersistenceState.NEW);
> > -        getObjectStore().registerNode(id, object);
> > -        getObjectStore().nodeCreated(id);
> >
> >         injectInitialValue(object);
> >
> > -        // invoke callbacks
> > -        getEntityResolver().getCallbackRegistry().performCallbacks(
> > -                LifecycleEvent.POST_ADD,
> > -                object);
> > -
> >         return object;
> >     }
> >
> > @@ -684,21 +673,17 @@
> >         else {
> >             persistent.setObjectId(new ObjectId(entity.getName()));
> >         }
> > -
> > -        persistent.setObjectContext(this);
> > -        persistent.setPersistenceState(PersistenceState.NEW);
> > -
> > -        getObjectStore().registerNode(persistent.getObjectId(), object);
> > -        getObjectStore().nodeCreated(persistent.getObjectId());
> > -
> > -        // now we need to find all arc changes, inject missing value
> > holders and pull in
> > -        // all transient connected objects
> > -
> > +
> >         ClassDescriptor descriptor =
> > getEntityResolver().getClassDescriptor(
> >                 entity.getName());
> >         if (descriptor == null) {
> >             throw new IllegalArgumentException("Invalid entity name: " +
> > entity.getName());
> >         }
> > +
> > +        injectInitialValue(object);
> > +
> > +        // now we need to find all arc changes, inject missing value
> > holders and pull in
> > +        // all transient connected objects
> >
> >         descriptor.visitProperties(new PropertyVisitor() {
> >
> > @@ -752,13 +737,6 @@
> >                 return true;
> >             }
> >         });
> > -
> > -        injectInitialValue(object);
> > -
> > -        // invoke callbacks
> > -        getEntityResolver().getCallbackRegistry().performCallbacks(
> > -                LifecycleEvent.POST_ADD,
> > -                persistent);
> >     }
> >
> >     /**
> > @@ -773,48 +751,6 @@
> >     }
> >
> >     /**
> > -     * Schedules all objects in the collection for deletion on the next
> > commit of this
> > -     * DataContext. Object's persistence state is changed to
> > PersistenceState.DELETED;
> > -     * objects related to this object are processed according to delete
> > rules, i.e.
> > -     * relationships can be unset ("nullify" rule), deletion operation
> is
> > cascaded
> > -     * (cascade rule).
> > -     * <p>
> > -     * <i>"Nullify" delete rule side effect: </i> passing a collection
> > representing
> > -     * to-many relationship with nullify delete rule may result in
> objects
> > being removed
> > -     * from collection.
> > -     * </p>
> > -     *
> > -     * @since 1.2
> > -     */
> > -    public void deleteObjects(Collection objects) {
> > -        if (objects.isEmpty()) {
> > -            return;
> > -        }
> > -
> > -        // clone object list... this maybe a relationship collection
> with
> > nullify delete
> > -        // rule, so modifying
> > -        for (Persistent object : new ArrayList<Persistent>(objects)) {
> > -            deleteObject(object);
> > -        }
> > -    }
> > -
> > -    /**
> > -     * Schedules an object for deletion on the next commit of this
> > DataContext. Object's
> > -     * persistence state is changed to PersistenceState.DELETED; objects
> > related to this
> > -     * object are processed according to delete rules, i.e.
> relationships
> > can be unset
> > -     * ("nullify" rule), deletion operation is cascaded (cascade rule).
> > -     *
> > -     * @param object a persistent object that we want to delete.
> > -     * @throws DeleteDenyException if a DENY delete rule is applicable
> for
> > object
> > -     *             deletion.
> > -     * @throws NullPointerException if object is null.
> > -     */
> > -    @Override
> > -    public void deleteObject(Object object) throws DeleteDenyException {
> > -        new DataContextDeleteAction(this).performDelete((Persistent)
> > object);
> > -    }
> > -
> > -    /**
> >      * If the parent channel is a DataContext, reverts local changes to
> > make this context
> >      * look like the parent, if the parent channel is a DataDomain,
> reverts
> > all changes.
> >      *
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
> > Wed Nov 18 12:08:20 2009
> > @@ -28,6 +28,7 @@
> >
> >  import org.apache.cayenne.CayenneRuntimeException;
> >  import org.apache.cayenne.DataChannel;
> > +import org.apache.cayenne.DataChannelSyncCallbackAction;
> >  import org.apache.cayenne.ObjectContext;
> >  import org.apache.cayenne.QueryResponse;
> >  import org.apache.cayenne.access.jdbc.BatchQueryBuilderFactory;
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
> > Wed Nov 18 12:08:20 2009
> > @@ -99,6 +99,7 @@
> >      */
> >     public void addListener(Class<?> entityClass, LifecycleListener
> > listener) {
> >         addListener(LifecycleEvent.POST_ADD, entityClass, listener,
> > "postAdd");
> > +        addListener(LifecycleEvent.POST_PERSIST, entityClass, listener,
> > "prePersist");
> >         addListener(LifecycleEvent.POST_PERSIST, entityClass, listener,
> > "postPersist");
> >         addListener(LifecycleEvent.PRE_REMOVE, entityClass, listener,
> > "preRemove");
> >         addListener(LifecycleEvent.POST_REMOVE, entityClass, listener,
> > "postRemove");
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/remote/ClientChannel.java
> > Wed Nov 18 12:08:20 2009
> > @@ -24,6 +24,7 @@
> >
> >  import org.apache.cayenne.CayenneRuntimeException;
> >  import org.apache.cayenne.DataChannel;
> > +import org.apache.cayenne.DataChannelSyncCallbackAction;
> >  import org.apache.cayenne.ObjectContext;
> >  import org.apache.cayenne.ObjectId;
> >  import org.apache.cayenne.Persistent;
> > @@ -169,6 +170,14 @@
> >             ObjectContext originatingContext,
> >             GraphDiff changes,
> >             int syncType) {
> > +
> > +        DataChannelSyncCallbackAction callbackAction =
> > DataChannelSyncCallbackAction
> > +            .getCallbackAction(
> > +                getEntityResolver().getCallbackRegistry(),
> > +                originatingContext.getGraphManager(),
> > +                changes,
> > +                syncType);
> > +        callbackAction.applyPreCommit();
> >
> >         changes = diffCompressor.compress(changes);
> >
> > @@ -221,6 +230,7 @@
> >             }
> >         }
> >
> > +        callbackAction.applyPostCommit();
> >         return replyDiff;
> >     }
> >
> >
> > Added:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java?rev=881740&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> > (added)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
> > Wed Nov 18 12:08:20 2009
> > @@ -0,0 +1,114 @@
> > +/*****************************************************************
> > + *   Licensed to the Apache Software Foundation (ASF) under one
> > + *  or more contributor license agreements.  See the NOTICE file
> > + *  distributed with this work for additional information
> > + *  regarding copyright ownership.  The ASF licenses this file
> > + *  to you under the Apache License, Version 2.0 (the
> > + *  "License"); you may not use this file except in compliance
> > + *  with the License.  You may obtain a copy of the License at
> > + *
> > + *    http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + *  Unless required by applicable law or agreed to in writing,
> > + *  software distributed under the License is distributed on an
> > + *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + *  KIND, either express or implied.  See the License for the
> > + *  specific language governing permissions and limitations
> > + *  under the License.
> > + ****************************************************************/
> > +package org.apache.cayenne.remote;
> > +
> > +import org.apache.cayenne.LifecycleListener;
> > +import org.apache.cayenne.ObjectContext;
> > +import org.apache.cayenne.testdo.mt.ClientMtLifecycles;
> > +
> > +public class RemoteCallbacksTest extends RemoteCayenneCase implements
> > LifecycleListener {
> > +    private int added, loaded, prePersisted, postPersisted, preRemoved,
> > postRemoved, preUpdated, postUpdated;
> > +
> > +    @Override
> > +    public void setUp() throws Exception {
> > +        super.setUp();
> > +        added = 0;
> > +        loaded = 0;
> > +        prePersisted = 0;
> > +        postPersisted = 0;
> > +        preRemoved = 0;
> > +        postRemoved = 0;
> > +        preUpdated = 0;
> > +        postUpdated = 0;
> > +    }
> > +
> > +    public void testDefault() throws InterruptedException {
> > +        ObjectContext context = createROPContext();
> > +
> >
>  context.getEntityResolver().getCallbackRegistry().addListener(ClientMtLifecycles.class,
> > this);
> > +
> > +        assertAll(0, 0, 0, 0, 0, 0, 0, 0);
> > +        ClientMtLifecycles l1 =
> > context.newObject(ClientMtLifecycles.class);
> > +
> > +        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
> > +        l1.setName("x");
> > +        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
> > +
> > +        context.commitChanges();
> > +        Thread.sleep(5); //until commit
> > +        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
> > +
> > +        l1.setName("x2");
> > +        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
> > +
> > +        context.commitChanges();
> > +        Thread.sleep(5); //until commit
> > +        assertAll(1, 0, 1, 1, 1, 1, 0, 0);
> > +
> > +        context.deleteObject(l1);
> > +        assertAll(1, 0, 1, 1, 1, 1, 1, 0);
> > +
> > +        context.commitChanges();
> > +        Thread.sleep(5); //until commit
> > +        assertAll(1, 0, 1, 1, 1, 1, 1, 1);
> > +    }
> > +
> > +    private void assertAll(int added, int loaded, int prePersisted, int
> > postPersisted,
> > +            int preUpdated, int postUpdated, int preRemoved, int
> > postRemoved) {
> > +        assertEquals(this.added, added);
> > +        assertEquals(this.loaded, loaded);
> > +        assertEquals(this.prePersisted, prePersisted);
> > +        assertEquals(this.postPersisted, postPersisted);
> > +        assertEquals(this.preRemoved, preRemoved);
> > +        assertEquals(this.postRemoved, postRemoved);
> > +        assertEquals(this.preUpdated, preUpdated);
> > +        assertEquals(this.postUpdated, postUpdated);
> > +    }
> > +
> > +    public void postAdd(Object entity) {
> > +        added++;
> > +    }
> > +
> > +    public void postLoad(Object entity) {
> > +        loaded++;
> > +    }
> > +
> > +    public void postPersist(Object entity) {
> > +        postPersisted++;
> > +    }
> > +
> > +    public void postRemove(Object entity) {
> > +        postRemoved++;
> > +    }
> > +
> > +    public void postUpdate(Object entity) {
> > +        postUpdated++;
> > +    }
> > +
> > +    public void prePersist(Object entity) {
> > +        prePersisted++;
> > +    }
> > +
> > +    public void preRemove(Object entity) {
> > +        preRemoved++;
> > +    }
> > +
> > +    public void preUpdate(Object entity) {
> > +        preUpdated++;
> > +    }
> > +}
> >
> > Added:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java?rev=881740&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> > (added)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtLifecycles.java
> > Wed Nov 18 12:08:20 2009
> > @@ -0,0 +1,10 @@
> > +package org.apache.cayenne.testdo.mt;
> > +
> > +import org.apache.cayenne.testdo.mt.auto._ClientMtLifecycles;
> > +
> > +/**
> > + * A persistent class mapped as "MtLifecycles" Cayenne entity.
> > + */
> > +public class ClientMtLifecycles extends _ClientMtLifecycles {
> > +
> > +}
> >
> > Added:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java?rev=881740&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> > (added)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtLifecycles.java
> > Wed Nov 18 12:08:20 2009
> > @@ -0,0 +1,7 @@
> > +package org.apache.cayenne.testdo.mt;
> > +
> > +import org.apache.cayenne.testdo.mt.auto._MtLifecycles;
> > +
> > +public class MtLifecycles extends _MtLifecycles {
> > +
> > +}
> >
> > Added:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java?rev=881740&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> > (added)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtLifecycles.java
> > Wed Nov 18 12:08:20 2009
> > @@ -0,0 +1,37 @@
> > +package org.apache.cayenne.testdo.mt.auto;
> > +
> > +import org.apache.cayenne.PersistentObject;
> > +
> > +/**
> > + * A generated persistent class mapped as "MtLifecycles" Cayenne entity.
> > It is a good idea to
> > + * avoid changing this class manually, since it will be overwritten next
> > time code is
> > + * regenerated. If you need to make any customizations, put them in a
> > subclass.
> > + */
> > +public abstract class _ClientMtLifecycles extends PersistentObject {
> > +
> > +    public static final String NAME_PROPERTY = "name";
> > +
> > +    protected String name;
> > +
> > +    public String getName() {
> > +        if(objectContext != null) {
> > +            objectContext.prepareForAccess(this, "name", false);
> > +        }
> > +
> > +        return name;
> > +    }
> > +    public void setName(String name) {
> > +        if(objectContext != null) {
> > +            objectContext.prepareForAccess(this, "name", false);
> > +        }
> > +
> > +        Object oldValue = this.name;
> > +        this.name = name;
> > +
> > +        // notify objectContext about simple property change
> > +        if(objectContext != null) {
> > +            objectContext.propertyChanged(this, "name", oldValue, name);
> > +        }
> > +    }
> > +
> > +}
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMultiTier.java
> > Wed Nov 18 12:08:20 2009
> > @@ -5,7 +5,7 @@
> >  import org.apache.cayenne.ObjectContext;
> >  import org.apache.cayenne.PersistentObject;
> >  import org.apache.cayenne.query.NamedQuery;
> > -import org.apache.cayenne.testdo.mt.ClientMtTable1;
> > +import org.apache.cayenne.testdo.mt.MtTable1;
> >
> >  /**
> >  * This class was generated by Cayenne.
> > @@ -15,15 +15,21 @@
> >  */
> >  public class _ClientMultiTier {
> >
> > -    public List<ClientMtTable1> performAllMtTable1(ObjectContext context
> )
> > {
> > +    public static final String ALL_MT_TABLE1_QUERYNAME = "AllMtTable1";
> > +
> > +    public static final String MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> > "MtQueryWithLocalCache";
> > +
> > +    public static final String
> > PARAMETERIZED_MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> > "ParameterizedMtQueryWithLocalCache";
> > +
> > +    public List<MtTable1> performAllMtTable1(ObjectContext context ) {
> >         return context.performQuery(new NamedQuery("AllMtTable1"));
> >     }
> >
> > -    public List<ClientMtTable1>
> performMtQueryWithLocalCache(ObjectContext
> > context ) {
> > +    public List<MtTable1> performMtQueryWithLocalCache(ObjectContext
> > context ) {
> >         return context.performQuery(new
> > NamedQuery("MtQueryWithLocalCache"));
> >     }
> >
> > -    public List<ClientMtTable1>
> > performParameterizedMtQueryWithLocalCache(ObjectContext context , String
> g)
> > {
> > +    public List<MtTable1>
> > performParameterizedMtQueryWithLocalCache(ObjectContext context , String
> g)
> > {
> >         String[] parameters = {
> >             "g",
> >         };
> >
> > Added:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java?rev=881740&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> > (added)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtLifecycles.java
> > Wed Nov 18 12:08:20 2009
> > @@ -0,0 +1,23 @@
> > +package org.apache.cayenne.testdo.mt.auto;
> > +
> > +import org.apache.cayenne.CayenneDataObject;
> > +
> > +/**
> > + * Class _MtLifecycles was generated by Cayenne.
> > + * It is probably a good idea to avoid changing this class manually,
> > + * since it may be overwritten next time code is regenerated.
> > + * If you need to make any customizations, please use subclass.
> > + */
> > +public abstract class _MtLifecycles extends CayenneDataObject {
> > +
> > +    public static final String NAME_PROPERTY = "name";
> > +
> > +
> > +    public void setName(String name) {
> > +        writeProperty("name", name);
> > +    }
> > +    public String getName() {
> > +        return (String)readProperty("name");
> > +    }
> > +
> > +}
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MultiTier.java
> > Wed Nov 18 12:08:20 2009
> > @@ -14,6 +14,12 @@
> >  */
> >  public class _MultiTier {
> >
> > +    public static final String ALL_MT_TABLE1_QUERYNAME = "AllMtTable1";
> > +
> > +    public static final String MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> > "MtQueryWithLocalCache";
> > +
> > +    public static final String
> > PARAMETERIZED_MT_QUERY_WITH_LOCAL_CACHE_QUERYNAME =
> > "ParameterizedMtQueryWithLocalCache";
> > +
> >     public List<MtTable1> performAllMtTable1(ObjectContext context ) {
> >         return context.performQuery(new NamedQuery("AllMtTable1"));
> >     }
> >
> > Modified:
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> > URL:
> >
> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml?rev=881740&r1=881739&r2=881740&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> > (original)
> > +++
> >
> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
> > Wed Nov 18 12:08:20 2009
> > @@ -29,6 +29,10 @@
> >                <db-attribute name="TABLE4_ID" type="INTEGER"
> > isPrimaryKey="true" isMandatory="true"/>
> >                <db-attribute name="TABLE5_ID" type="INTEGER"
> > isPrimaryKey="true" isMandatory="true"/>
> >        </db-entity>
> > +       <db-entity name="MT_LIFECYCLES">
> > +               <db-attribute name="ID" type="INTEGER"
> isPrimaryKey="true"
> > isMandatory="true"/>
> > +               <db-attribute name="NAME" type="VARCHAR"
> isMandatory="true"
> > length="100"/>
> > +       </db-entity>
> >        <db-entity name="MT_MAP_TO_MANY">
> >                <db-attribute name="ID" type="INTEGER" isPrimaryKey="true"
> > isMandatory="true"/>
> >        </db-entity>
> > @@ -91,6 +95,9 @@
> >        <obj-entity name="MtDeleteRule"
> > className="org.apache.cayenne.testdo.mt.MtDeleteRule"
> > clientClassName="org.apache.cayenne.testdo.mt.ClientMtDeleteRule"
> > dbEntityName="MT_DELETE_RULE">
> >                <obj-attribute name="name" type="java.lang.String"
> > db-attribute-path="NAME"/>
> >        </obj-entity>
> > +       <obj-entity name="MtLifecycles"
> > className="org.apache.cayenne.testdo.mt.MtLifecycles"
> > clientClassName="org.apache.cayenne.testdo.mt.ClientMtLifecycles"
> > dbEntityName="MT_LIFECYCLES">
> > +               <obj-attribute name="name" type="java.lang.String"
> > db-attribute-path="NAME"/>
> > +       </obj-entity>
> >        <obj-entity name="MtMapToMany"
> > className="org.apache.cayenne.testdo.mt.MtMapToMany"
> > clientClassName="org.apache.cayenne.testdo.mt.ClientMtMapToMany"
> > dbEntityName="MT_MAP_TO_MANY">
> >        </obj-entity>
> >        <obj-entity name="MtMapToManyTarget"
> > className="org.apache.cayenne.testdo.mt.MtMapToManyTarget"
> > clientClassName="org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget"
> > dbEntityName="MT_MAP_TO_MANY_TARGET">
> >
> >
> >
>
>
> --
> Olga Tkacheva
>



-- 
Andrey