You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/04/05 18:44:12 UTC
svn commit: r762115 - in /cayenne/main/trunk: docs/doc/src/main/resources/
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/
framework/cayenne-jdk1.5-unpu...
Author: aadamchik
Date: Sun Apr 5 16:44:11 2009
New Revision: 762115
URL: http://svn.apache.org/viewvc?rev=762115&view=rev
Log:
CAY-1204 Incorrect relationship syncing in nested CayenneContext's
unit tests, fix
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/PropertyChangeProcessingStrategy.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java
- copied, changed from r761544, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/NestedObjectContextTest.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneDep.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneMaster.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneDep.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneMaster.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneDep.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneMaster.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneDep.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneMaster.java
Removed:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/NestedObjectContextTest.java
Modified:
cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
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/CayenneContextGraphAction.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/ChildDiffLoader.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/multi-tier.map.xml
Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=762115&r1=762114&r2=762115&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Sun Apr 5 16:44:11 2009
@@ -49,6 +49,8 @@
CAY-1183 commitToParent() makes object persistence state committed, produces exception when using object in parent context (ROP)
CAY-1194 problems with relationships when using nested contexts and ROP
CAY-1196 CayenneRuntimeException in modeler due to ClassNotFoundException when java type is invalid and db attribute is null
+CAY-1204 Incorrect relationship syncing in nested CayenneContext's
+
----------------------------------
Release: 3.0M5
Date: 15 Dec 2008
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=762115&r1=762114&r2=762115&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 Sun Apr 5 16:44:11 2009
@@ -25,7 +25,6 @@
import java.util.List;
import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.graph.ChildDiffLoader;
import org.apache.cayenne.graph.CompoundDiff;
import org.apache.cayenne.graph.GraphDiff;
import org.apache.cayenne.graph.GraphManager;
@@ -46,6 +45,17 @@
*/
public class CayenneContext extends BaseContext {
+ /**
+ * @since 3.0
+ */
+ private static ThreadLocal<PropertyChangeProcessingStrategy> PROPERTY_CHANGE_PROCESSING_STRATEGY = new ThreadLocal<PropertyChangeProcessingStrategy>() {
+
+ @Override
+ protected PropertyChangeProcessingStrategy initialValue() {
+ return PropertyChangeProcessingStrategy.RECORD_AND_PROCESS_REVERSE_ARCS;
+ }
+ };
+
protected EntityResolver entityResolver;
CayenneContextGraphManager graphManager;
@@ -60,11 +70,6 @@
CayenneContextMergeHandler mergeHandler;
/**
- * @since 3.0
- */
- boolean propertyChangeCallbacksDisabled;
-
- /**
* Creates a new CayenneContext with no channel and disabled graph events.
*/
public CayenneContext() {
@@ -98,6 +103,24 @@
}
/**
+ * @since 3.0
+ */
+ // accesses a static thread local variable... still keeping the method non-static for
+ // better future portability...
+ PropertyChangeProcessingStrategy getPropertyChangeProcessingStrategy() {
+ return PROPERTY_CHANGE_PROCESSING_STRATEGY.get();
+ }
+
+ /**
+ * @since 3.0
+ */
+ // accesses a static thread local variable... still keeping the method non-static for
+ // better future portability...
+ void setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy strategy) {
+ PROPERTY_CHANGE_PROCESSING_STRATEGY.set(strategy);
+ }
+
+ /**
* Sets the context channel, setting up a listener for channel events.
*/
public void setChannel(DataChannel channel) {
@@ -136,7 +159,8 @@
* Returns true if this context posts lifecycle events. Subjects used for these events
* are
* <code>ObjectContext.GRAPH_COMMIT_STARTED_SUBJECT, ObjectContext.GRAPH_COMMITTED_SUBJECT,
- * ObjectContext.GRAPH_COMMIT_ABORTED_SUBJECT, ObjectContext.GRAPH_ROLLEDBACK_SUBJECT.</code>.
+ * ObjectContext.GRAPH_COMMIT_ABORTED_SUBJECT, ObjectContext.GRAPH_ROLLEDBACK_SUBJECT.</code>
+ * .
*/
public boolean isLifecycleEventsEnabled() {
return graphManager.lifecycleEventsEnabled;
@@ -226,7 +250,7 @@
graphManager.graphCommitStarted();
GraphDiff changes = graphManager.getDiffsSinceLastFlush();
-
+
try {
commitDiff = channel.onSync(this, changes, syncType);
}
@@ -242,7 +266,7 @@
}
graphManager.graphCommitted(commitDiff);
-
+
// this event is caught by peer nested ObjectContexts to synchronize the
// state
fireDataChannelCommitted(this, changes);
@@ -277,7 +301,7 @@
if (graphManager.hasChanges()) {
GraphDiff diff = graphManager.getDiffs();
graphManager.graphReverted();
-
+
fireDataChannelRolledback(this, diff);
}
}
@@ -442,7 +466,7 @@
Object oldValue,
Object newValue) {
- if (!isPropertyChangeCallbacksDisabled()) {
+ if (getPropertyChangeProcessingStrategy() != PropertyChangeProcessingStrategy.IGNORE) {
graphAction.handlePropertyChange(object, property, oldValue, newValue);
}
}
@@ -482,8 +506,8 @@
String entityName,
ClassDescriptor descriptor) {
/**
- * We should create new id only if it is not set for this object.
- * It could have been created, for instance, in child context
+ * We should create new id only if it is not set for this object. It could have
+ * been created, for instance, in child context
*/
ObjectId id = object.getObjectId();
if (id == null) {
@@ -521,26 +545,14 @@
}
/**
- * @since 3.0
- */
- boolean isPropertyChangeCallbacksDisabled() {
- return propertyChangeCallbacksDisabled;
- }
-
- /**
- * @since 3.0
- */
- void setPropertyChangeCallbacksDisabled(boolean propertyChangeCallbacksDisabled) {
- this.propertyChangeCallbacksDisabled = propertyChangeCallbacksDisabled;
- }
-
- /**
* Creates and returns a new child ObjectContext.
*
* @since 3.0
*/
public ObjectContext createChildContext() {
- return new CayenneContext(this, graphManager.changeEventsEnabled,
+ return new CayenneContext(
+ this,
+ graphManager.changeEventsEnabled,
graphManager.lifecycleEventsEnabled);
}
@@ -553,13 +565,22 @@
boolean childContext = this != originatingContext && changes != null;
if (childContext) {
- changes.apply(new CayenneContextChildDiffLoader(this));
- fireDataChannelChanged(originatingContext, changes);
+
+ PropertyChangeProcessingStrategy oldStrategy = getPropertyChangeProcessingStrategy();
+ setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy.RECORD);
+ try {
+ changes.apply(new CayenneContextChildDiffLoader(this));
+ }
+ finally {
+ setPropertyChangeProcessingStrategy(oldStrategy);
+ }
+
+ fireDataChannelChanged(originatingContext, changes);
}
return (cascade) ? doCommitChanges(true) : new CompoundDiff();
}
-
+
/**
* Returns <code>true</code> if there are any modified, deleted or new objects
* registered with this CayenneContext, <code>false</code> otherwise.
@@ -567,30 +588,4 @@
public boolean hasChanges() {
return graphManager.hasChanges();
}
-
- /**
- * Class for loading child's CayenneContext changes to parent context.
- * Required to register diffs in CayenneContext's graph manager when node's simple property changes:
- * CayenneContext's way of setting properties differs from DataContext's, and method of notifying
- * graph manager is sealed in every 'set' method of Cayenne Client Data Object class.
- * So here we should notify graph manager too, so that objects's state will update and they will
- * be marked as dirty.
- */
- class CayenneContextChildDiffLoader extends ChildDiffLoader {
- public CayenneContextChildDiffLoader(ObjectContext context) {
- super(context);
- }
-
- @Override
- public void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
- super.nodePropertyChanged(nodeId, property, oldValue, newValue);
-
- Persistent object = (Persistent) getGraphManager().getNode(nodeId);
- propertyChanged(object, property, oldValue, newValue);
- }
- }
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,177 @@
+/*****************************************************************
+ * 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;
+
+import org.apache.cayenne.graph.ChildDiffLoader;
+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;
+
+/**
+ * Used for loading child's CayenneContext changes to parent context.
+ *
+ * @since 3.0
+ */
+class CayenneContextChildDiffLoader extends ChildDiffLoader {
+
+ public CayenneContextChildDiffLoader(CayenneContext context) {
+ super(context);
+ }
+
+ @Override
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+
+ super.nodePropertyChanged(nodeId, property, oldValue, newValue);
+
+ Persistent object = (Persistent) context.getGraphManager().getNode(nodeId);
+ context.propertyChanged(object, property, oldValue, newValue);
+ }
+
+ @Override
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+
+ final Persistent source = findObject(nodeId);
+ final Persistent target = findObject(targetNodeId);
+
+ // if a target was later deleted, the diff for arcCreated is still preserved and
+ // can result in NULL target here.
+ if (target == null) {
+ return;
+ }
+
+ ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
+ ((ObjectId) nodeId).getEntityName());
+ ArcProperty property = (ArcProperty) descriptor.getProperty(arcId.toString());
+
+ // TODO: context strategy reset here still hides the difference between to-one and
+ // to-many per CAY-1204... hopefully it will go away if we do refactoring around
+ // property change strategy instead of using "changeX vs. changeXDirectly".
+ PropertyChangeProcessingStrategy oldStrategy = ((CayenneContext) context)
+ .getPropertyChangeProcessingStrategy();
+ ((CayenneContext) context)
+ .setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy.IGNORE);
+ try {
+ property.visit(new PropertyVisitor() {
+
+ public boolean visitAttribute(AttributeProperty property) {
+ return false;
+ }
+
+ public boolean visitToMany(ToManyProperty property) {
+ // connect reverse arc if the relationship is marked as "runtime"
+ ArcProperty reverseArc = property.getComplimentaryReverseArc();
+ boolean autoConnectReverse = reverseArc != null
+ && reverseArc.getRelationship().isRuntime();
+
+ property.addTarget(source, target, autoConnectReverse);
+ return false;
+ }
+
+ public boolean visitToOne(ToOneProperty property) {
+ property.setTarget(source, target, false);
+ return false;
+ }
+ });
+ }
+ finally {
+ ((CayenneContext) context).setPropertyChangeProcessingStrategy(oldStrategy);
+ }
+
+ context.propertyChanged(source, (String) arcId, null, target);
+ }
+
+ @Override
+ public void arcDeleted(Object nodeId, final Object targetNodeId, Object arcId) {
+ final Persistent source = findObject(nodeId);
+
+ // needed as sometime temporary objects are evoked from the context before
+ // changing their relationships
+ if (source == null) {
+ return;
+ }
+
+ ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
+ ((ObjectId) nodeId).getEntityName());
+ Property property = descriptor.getProperty(arcId.toString());
+
+ // TODO: context strategy reset here still hides the difference between to-one and
+ // to-many per CAY-1204... hopefully it will go away if we do refactoring around
+ // property change strategy instead of using "changeX vs. changeXDirectly".
+ PropertyChangeProcessingStrategy oldStrategy = ((CayenneContext) context)
+ .getPropertyChangeProcessingStrategy();
+ ((CayenneContext) context)
+ .setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy.IGNORE);
+ final Persistent[] target = new Persistent[1];
+ target[0] = findObject(targetNodeId);
+
+ try {
+ property.visit(new PropertyVisitor() {
+
+ public boolean visitAttribute(AttributeProperty property) {
+ return false;
+ }
+
+ public boolean visitToMany(ToManyProperty property) {
+ // connect reverse arc if the relationship is marked as "runtime"
+ ArcProperty reverseArc = property.getComplimentaryReverseArc();
+ boolean autoConnectReverse = reverseArc != null
+ && reverseArc.getRelationship().isRuntime();
+
+ if (target[0] == null) {
+
+ // this is usually the case when a NEW object was deleted and then
+ // its relationships were manipulated; so try to locate the object
+ // in the collection ... the performance of this is rather dubious
+ // of course...
+ target[0] = findObjectInCollection(targetNodeId, property
+ .readProperty(source));
+ }
+
+ if (target[0] == null) {
+ // ignore?
+ }
+ else {
+ property.removeTarget(source, target[0], autoConnectReverse);
+ }
+
+ return false;
+ }
+
+ public boolean visitToOne(ToOneProperty property) {
+ property.setTarget(source, null, false);
+ return false;
+ }
+ });
+ }
+ finally {
+ ((CayenneContext) context).setPropertyChangeProcessingStrategy(oldStrategy);
+ }
+
+ context.propertyChanged(source, (String) arcId, target[0], null);
+ }
+
+}
\ No newline at end of file
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphAction.java?rev=762115&r1=762114&r2=762115&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphAction.java Sun Apr 5 16:44:11 2009
@@ -42,7 +42,7 @@
}
};
- CayenneContextGraphAction(ObjectContext context) {
+ CayenneContextGraphAction(CayenneContext context) {
super(context);
}
@@ -57,6 +57,9 @@
return;
}
+ boolean processsReverse = ((CayenneContext) context)
+ .getPropertyChangeProcessingStrategy() == PropertyChangeProcessingStrategy.RECORD_AND_PROCESS_REVERSE_ARCS;
+
// prevent reverse actions down the stack
setArcChangeInProcess(true);
@@ -67,7 +70,10 @@
((Persistent) oldValue).getObjectId(),
property.getName());
- unsetReverse(property, object, (Persistent) oldValue);
+ if (processsReverse) {
+ unsetReverse(property, object, (Persistent) oldValue);
+ }
+
markAsDirty(object);
}
@@ -77,7 +83,10 @@
((Persistent) newValue).getObjectId(),
property.getName());
- setReverse(property, object, (Persistent) newValue);
+ if (processsReverse) {
+ setReverse(property, object, (Persistent) newValue);
+ }
+
markAsDirty(object);
}
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java?rev=762115&r1=762114&r2=762115&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java Sun Apr 5 16:44:11 2009
@@ -135,14 +135,14 @@
}
remapTargets();
-
+
stateLog.graphCommitted();
reset();
if (lifecycleEventsEnabled) {
// include all diffs after the commit start marker.
- //We fire event as if it was posted by parent channel, so that
- //nested contexts could catch it
+ // We fire event as if it was posted by parent channel, so that
+ // nested contexts could catch it
context.fireDataChannelCommitted(context.getChannel(), parentSyncDiff);
}
}
@@ -158,8 +158,10 @@
EntityResolver resolver = context.getEntityResolver();
// avoid processing callbacks when updating the map...
- boolean changeCallbacks = context.isPropertyChangeCallbacksDisabled();
- context.setPropertyChangeCallbacksDisabled(true);
+ PropertyChangeProcessingStrategy oldChangeStrategy = context
+ .getPropertyChangeProcessingStrategy();
+ context
+ .setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy.IGNORE);
try {
while (it.hasNext()) {
@@ -186,7 +188,7 @@
}
}
finally {
- context.setPropertyChangeCallbacksDisabled(changeCallbacks);
+ context.setPropertyChangeProcessingStrategy(oldChangeStrategy);
}
}
@@ -337,6 +339,7 @@
* This change handler is used to perform rollback actions for Cayenne context
*/
class RollbackChangeHandler implements GraphChangeHandler {
+
public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
context.mergeHandler.arcCreated(nodeId, targetNodeId, arcId);
CayenneContextGraphManager.this.arcCreated(nodeId, targetNodeId, arcId);
@@ -356,15 +359,20 @@
}
/**
- * Need to write property directly to this context
+ * Need to write property directly to this context
*/
public void nodePropertyChanged(
Object nodeId,
String property,
Object oldValue,
Object newValue) {
- context.mergeHandler.nodePropertyChanged(nodeId, property, oldValue, newValue);
- CayenneContextGraphManager.this.nodePropertyChanged(nodeId, property, oldValue, newValue);
+ context.mergeHandler
+ .nodePropertyChanged(nodeId, property, oldValue, newValue);
+ CayenneContextGraphManager.this.nodePropertyChanged(
+ nodeId,
+ property,
+ oldValue,
+ newValue);
}
public void nodeRemoved(Object nodeId) {
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/PropertyChangeProcessingStrategy.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/PropertyChangeProcessingStrategy.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/PropertyChangeProcessingStrategy.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/PropertyChangeProcessingStrategy.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,48 @@
+/*****************************************************************
+ * 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;
+
+/**
+ * Defines how ObjectContext should behave in response to
+ * {@link ObjectContext#propertyChanged(Persistent, String, Object, Object)} calls.
+ *
+ * @since 3.0
+ */
+enum PropertyChangeProcessingStrategy {
+
+ /**
+ * A strategy that does no extra processing of property changes. Usually used when
+ * already committed changes are merged from a downstream channel.
+ */
+ IGNORE,
+
+ /**
+ * A strategy that records the change in the change log and marks participating
+ * objects as dirty, but no attempt is made to process reverse relationships. Usually
+ * used when processing changes from an upstream (child) context.
+ */
+ RECORD,
+
+ /**
+ * A strategy that records the change in the change log and marks participating
+ * objects as dirty, and then initiates a complimentary change to the reverse
+ * relationships. The default operation mode used for changes initiated by the user.
+ */
+ RECORD_AND_PROCESS_REVERSE_ARCS;
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/ChildDiffLoader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/ChildDiffLoader.java?rev=762115&r1=762114&r2=762115&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/ChildDiffLoader.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/graph/ChildDiffLoader.java Sun Apr 5 16:44:11 2009
@@ -42,13 +42,15 @@
/**
* A GraphChangeHandler that loads child ObjectContext diffs into a parent ObjectContext.
- * Graph node ids are expected to be ObjectIds.
- * This class is made public since 3.0 to be used in ObjectContext synchronizing
+ * Graph node ids are expected to be ObjectIds. This class is made public since 3.0 to be
+ * used in ObjectContext synchronizing
*
* @since 1.2
*/
public class ChildDiffLoader implements GraphChangeHandler {
+ // TODO: andrus 04/05/2009 - replace with PropertyChangeProcessingStrategy enum used
+ // in ROP?
static final ThreadLocal<Boolean> childDiffProcessing = new ThreadLocal<Boolean>() {
@Override
@@ -57,7 +59,7 @@
}
};
- private ObjectContext context;
+ protected ObjectContext context;
/**
* Returns whether child diff processing is in progress.
@@ -142,8 +144,8 @@
((ObjectId) nodeId).getEntityName());
setExternalChange(Boolean.TRUE);
- try {
- descriptor.getProperty(property).writeProperty(object, null, newValue);
+ try {
+ descriptor.getProperty(property).writeProperty(object, null, newValue);
}
catch (Exception e) {
throw new CayenneRuntimeException("Error setting property: " + property, e);
@@ -259,7 +261,7 @@
}
}
- Persistent findObject(Object nodeId) {
+ protected Persistent findObject(Object nodeId) {
// first do a lookup in ObjectStore; if even a hollow object is found, return it;
// if not - fetch.
@@ -293,7 +295,7 @@
return (Persistent) objects.get(0);
}
- Persistent findObjectInCollection(Object nodeId, Object toManyHolder) {
+ protected Persistent findObjectInCollection(Object nodeId, Object toManyHolder) {
Collection c = (toManyHolder instanceof Map)
? ((Map) toManyHolder).values()
: (Collection) toManyHolder;
Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java (from r761544, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/NestedObjectContextTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/NestedObjectContextTest.java&r1=761544&r2=762115&rev=762115&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/remote/NestedObjectContextTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java Sun Apr 5 16:44:11 2009
@@ -16,26 +16,27 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.remote;
+package org.apache.cayenne;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import org.apache.cayenne.DataObjectUtils;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
+import org.apache.cayenne.graph.GraphChangeHandler;
+import org.apache.cayenne.graph.GraphDiff;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.remote.RemoteCayenneCase;
import org.apache.cayenne.testdo.mt.ClientMtTable1;
import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.testdo.mt.ClientMtTooneDep;
+import org.apache.cayenne.testdo.mt.ClientMtTooneMaster;
/**
* Tests nested object contexts
*/
-public class NestedObjectContextTest extends RemoteCayenneCase {
+public class NestedCayenneContextTest extends RemoteCayenneCase {
+
public void testChannels() {
ObjectContext child = context.createChildContext();
@@ -65,7 +66,8 @@
ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
- ClientMtTable1 hollow = (ClientMtTable1) context.localObject(new ObjectId("MtTable1"), null);
+ ClientMtTable1 hollow = (ClientMtTable1) context.localObject(new ObjectId(
+ "MtTable1"), null);
assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
@@ -90,13 +92,16 @@
assertSame(child, hollowPeer.getObjectContext());
assertSame(context, hollow.getObjectContext());
- Persistent committedPeer = child.localObject(committed.getObjectId(), committed);
+ Persistent committedPeer = child.localObject(
+ committed.getObjectId(),
+ committed);
assertEquals(PersistenceState.COMMITTED, committedPeer.getPersistenceState());
assertEquals(committed.getObjectId(), committedPeer.getObjectId());
assertSame(child, committedPeer.getObjectContext());
assertSame(context, committed.getObjectContext());
- ClientMtTable1 modifiedPeer = (ClientMtTable1) child.localObject(modified.getObjectId(), modified);
+ ClientMtTable1 modifiedPeer = (ClientMtTable1) child.localObject(modified
+ .getObjectId(), modified);
assertEquals(PersistenceState.COMMITTED, modifiedPeer.getPersistenceState());
assertEquals(modified.getObjectId(), modifiedPeer.getObjectId());
assertEquals("a", modifiedPeer.getGlobalAttribute1());
@@ -123,7 +128,8 @@
context.commitChanges();
ClientMtTable1 peerModified = (ClientMtTable1) DataObjectUtils.objectForQuery(
- child, new ObjectIdQuery(modified.getObjectId()));
+ child,
+ new ObjectIdQuery(modified.getObjectId()));
modified.setGlobalAttribute1("M1");
peerModified.setGlobalAttribute1("M2");
@@ -135,7 +141,8 @@
try {
- Persistent peerModified2 = child.localObject(modified.getObjectId(), modified);
+ Persistent peerModified2 = child
+ .localObject(modified.getObjectId(), modified);
assertSame(peerModified, peerModified2);
assertEquals(PersistenceState.MODIFIED, peerModified2.getPersistenceState());
assertEquals("M2", peerModified.getGlobalAttribute1());
@@ -158,10 +165,13 @@
blockQueries();
try {
- ClientMtTable2 child2 = (ClientMtTable2) child.localObject(_new2.getObjectId(), _new2);
+ ClientMtTable2 child2 = (ClientMtTable2) child.localObject(_new2
+ .getObjectId(), _new2);
assertEquals(PersistenceState.COMMITTED, child2.getPersistenceState());
assertNotNull(child2.getTable1());
- assertEquals(PersistenceState.COMMITTED, child2.getTable1().getPersistenceState());
+ assertEquals(PersistenceState.COMMITTED, child2
+ .getTable1()
+ .getPersistenceState());
}
finally {
unblockQueries();
@@ -313,7 +323,8 @@
context.commitChanges();
ClientMtTable2 p = child.newObject(ClientMtTable2.class);
- ClientMtTable1 aChild = (ClientMtTable1) DataObjectUtils.objectForPK(child, a.getObjectId());
+ ClientMtTable1 aChild = (ClientMtTable1) DataObjectUtils.objectForPK(child, a
+ .getObjectId());
p.setGlobalAttribute("X");
aChild.addToTable2Array(p);
@@ -340,7 +351,8 @@
ObjectContext child = context.createChildContext();
ObjectContext childPeer = context.createChildContext();
- ClientMtTable2 childP1 = (ClientMtTable2) DataObjectUtils.objectForPK(child, b.getObjectId());
+ ClientMtTable2 childP1 = (ClientMtTable2) DataObjectUtils.objectForPK(child, b
+ .getObjectId());
// trigger object creation in the peer nested DC
DataObjectUtils.objectForPK(childPeer, b.getObjectId());
@@ -358,6 +370,41 @@
assertNotNull(parentP1);
assertEquals(PersistenceState.MODIFIED, parentP1.getPersistenceState());
assertNull(parentP1.getTable1());
+
+ // check that arc changes got recorded in the parent context
+ GraphDiff diffs = context.internalGraphManager().getDiffs();
+ final int[] arcDiffs = new int[1];
+
+ diffs.apply(new GraphChangeHandler() {
+
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]++;
+ }
+
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]--;
+ }
+
+ public void nodeCreated(Object nodeId) {
+
+ }
+
+ public void nodeIdChanged(Object nodeId, Object newId) {
+ }
+
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ }
+
+ public void nodeRemoved(Object nodeId) {
+
+ }
+ });
+
+ assertEquals(-2, arcDiffs[0]);
}
finally {
unblockQueries();
@@ -405,14 +452,18 @@
assertEquals(PersistenceState.COMMITTED, childCommitted.getPersistenceState());
assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
- ClientMtTable1 parentNew = (ClientMtTable1) context.getGraphManager().getNode(
- childNew.getObjectId());
- ClientMtTable1 parentModified = (ClientMtTable1) context.getGraphManager().getNode(
- childModified.getObjectId());
- ClientMtTable1 parentCommitted = (ClientMtTable1) context.getGraphManager().getNode(
- childCommitted.getObjectId());
- ClientMtTable1 parentHollow = (ClientMtTable1) context.getGraphManager().getNode(
- childHollow.getObjectId());
+ ClientMtTable1 parentNew = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childNew.getObjectId());
+ final ClientMtTable1 parentModified = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childModified.getObjectId());
+ ClientMtTable1 parentCommitted = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childCommitted.getObjectId());
+ ClientMtTable1 parentHollow = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childHollow.getObjectId());
assertNotNull(parentNew);
assertEquals(PersistenceState.NEW, parentNew.getPersistenceState());
@@ -427,6 +478,46 @@
.getPersistenceState());
assertNotNull(parentHollow);
+
+ // check that arc changes got recorded in the parent context
+ GraphDiff diffs = context.internalGraphManager().getDiffs();
+
+ final int[] modifiedProperties = new int[1];
+
+ diffs.apply(new GraphChangeHandler() {
+
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+
+ }
+
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+
+ }
+
+ public void nodeCreated(Object nodeId) {
+
+ }
+
+ public void nodeIdChanged(Object nodeId, Object newId) {
+ }
+
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+
+ if (nodeId.equals(parentModified.getObjectId())) {
+ modifiedProperties[0]++;
+ }
+ }
+
+ public void nodeRemoved(Object nodeId) {
+
+ }
+ });
+
+ assertEquals(1, modifiedProperties[0]);
}
finally {
unblockQueries();
@@ -465,8 +556,9 @@
assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
- ClientMtTable1 parentDeleted = (ClientMtTable1) context.getGraphManager().getNode(
- childDeleted.getObjectId());
+ ClientMtTable1 parentDeleted = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childDeleted.getObjectId());
assertNotNull(parentDeleted);
assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
@@ -516,12 +608,15 @@
ClientMtTable1 parentNew = (ClientMtTable1) context.getGraphManager().getNode(
childNew.getObjectId());
- ClientMtTable1 parentModified = (ClientMtTable1) context.getGraphManager().getNode(
- childModified.getObjectId());
- ClientMtTable1 parentCommitted = (ClientMtTable1) context.getGraphManager().getNode(
- childCommitted.getObjectId());
- ClientMtTable1 parentDeleted = (ClientMtTable1) context.getGraphManager().getNode(
- childDeleted.getObjectId());
+ ClientMtTable1 parentModified = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childModified.getObjectId());
+ ClientMtTable1 parentCommitted = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childCommitted.getObjectId());
+ ClientMtTable1 parentDeleted = (ClientMtTable1) context
+ .getGraphManager()
+ .getNode(childDeleted.getObjectId());
ClientMtTable1 parentHollow = (ClientMtTable1) context.getGraphManager().getNode(
childHollow.getObjectId());
@@ -580,7 +675,8 @@
assertEquals(PersistenceState.MODIFIED, a.getPersistenceState());
child.commitChangesToParent();
- ClientMtTable1 parentA = (ClientMtTable1) context.getGraphManager().getNode(a.getObjectId());
+ ClientMtTable1 parentA = (ClientMtTable1) context.getGraphManager().getNode(
+ a.getObjectId());
assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
assertEquals(PersistenceState.MODIFIED, parentA.getPersistenceState());
assertEquals(1, parentA.getTable2Array().size());
@@ -604,7 +700,9 @@
context.commitChanges();
ObjectContext child = context.createChildContext();
- ClientMtTable1 childMt = (ClientMtTable1) DataObjectUtils.objectForPK(child, parentMt.getObjectId());
+ ClientMtTable1 childMt = (ClientMtTable1) DataObjectUtils.objectForPK(
+ child,
+ parentMt.getObjectId());
childMt.setGlobalAttribute1("1183");
ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
childMt2.setGlobalAttribute("1183");
@@ -612,32 +710,160 @@
child.commitChangesToParent();
- //fetching other relationship... this fails per CAY-1183
+ // fetching other relationship... this fails per CAY-1183
childMt2.getTable3();
}
-
+
public void testCAY1194() throws Exception {
deleteTestData();
-
- ClientMtTable1 parentMt = context.newObject(ClientMtTable1.class);
+
+ ClientMtTable1 parentMt = context.newObject(ClientMtTable1.class);
ObjectContext child = context.createChildContext();
-
+
ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
childMt2.setGlobalAttribute("222");
-
- ClientMtTable1 localParentMt = (ClientMtTable1) child.localObject(parentMt.getObjectId(), null);
+
+ ClientMtTable1 localParentMt = (ClientMtTable1) child.localObject(parentMt
+ .getObjectId(), null);
assertEquals(0, parentMt.getTable2Array().size());
assertEquals(0, localParentMt.getTable2Array().size());
-
+
childMt2.setTable1(localParentMt);
-
+
assertEquals(0, parentMt.getTable2Array().size());
assertEquals(1, localParentMt.getTable2Array().size());
-
- assertEquals(((Persistent) localParentMt.getTable2Array().get(0)).getObjectContext(), child);
-
+
+ assertEquals(((Persistent) localParentMt.getTable2Array().get(0))
+ .getObjectContext(), child);
+
child.commitChangesToParent();
assertEquals(1, parentMt.getTable2Array().size());
- assertEquals(((Persistent) parentMt.getTable2Array().get(0)).getObjectContext(), context);
+ assertEquals(
+ ((Persistent) parentMt.getTable2Array().get(0)).getObjectContext(),
+ context);
+ }
+
+ public void testCommitChangesToParentOneToMany() throws Exception {
+ deleteTestData();
+
+ ObjectContext child = context.createChildContext();
+
+ ClientMtTable1 master = child.newObject(ClientMtTable1.class);
+ ClientMtTable2 dep = child.newObject(ClientMtTable2.class);
+ master.addToTable2Array(dep);
+
+ child.commitChangesToParent();
+
+ ClientMtTable1 masterParent = (ClientMtTable1) context.getGraphManager().getNode(
+ master.getObjectId());
+ ClientMtTable2 depParent = (ClientMtTable2) context.getGraphManager().getNode(
+ dep.getObjectId());
+
+ assertNotNull(masterParent);
+ assertNotNull(depParent);
+
+ assertSame(masterParent, depParent.getTable1());
+ assertTrue(masterParent.getTable2Array().contains(depParent));
+
+ // check that arc changes got recorded in the parent context
+ GraphDiff diffs = context.internalGraphManager().getDiffs();
+
+ final int[] arcDiffs = new int[1];
+ final int[] newNodes = new int[1];
+
+ diffs.apply(new GraphChangeHandler() {
+
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]++;
+ }
+
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]--;
+ }
+
+ public void nodeCreated(Object nodeId) {
+ newNodes[0]++;
+ }
+
+ public void nodeIdChanged(Object nodeId, Object newId) {
+ }
+
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ }
+
+ public void nodeRemoved(Object nodeId) {
+ newNodes[0]--;
+ }
+ });
+
+ assertEquals(2, newNodes[0]);
+ assertEquals(2, arcDiffs[0]);
+ }
+
+ public void testCommitChangesToParentOneToOne() throws Exception {
+ deleteTestData();
+
+ ObjectContext child = context.createChildContext();
+
+ ClientMtTooneMaster master = child.newObject(ClientMtTooneMaster.class);
+ ClientMtTooneDep dep = child.newObject(ClientMtTooneDep.class);
+ master.setToDependent(dep);
+
+ child.commitChangesToParent();
+
+ ClientMtTooneMaster masterParent = (ClientMtTooneMaster) context
+ .getGraphManager()
+ .getNode(master.getObjectId());
+ ClientMtTooneDep depParent = (ClientMtTooneDep) context
+ .getGraphManager()
+ .getNode(dep.getObjectId());
+
+ assertNotNull(masterParent);
+ assertNotNull(depParent);
+
+ assertSame(masterParent, depParent.getToMaster());
+ assertSame(depParent, masterParent.getToDependent());
+
+ // check that arc changes got recorded in the parent context
+ GraphDiff diffs = context.internalGraphManager().getDiffs();
+
+ final int[] arcDiffs = new int[1];
+ final int[] newNodes = new int[1];
+
+ diffs.apply(new GraphChangeHandler() {
+
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]++;
+ }
+
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+ arcDiffs[0]--;
+ }
+
+ public void nodeCreated(Object nodeId) {
+ newNodes[0]++;
+ }
+
+ public void nodeIdChanged(Object nodeId, Object newId) {
+ }
+
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ }
+
+ public void nodeRemoved(Object nodeId) {
+ newNodes[0]--;
+ }
+ });
+
+ assertEquals(2, newNodes[0]);
+ assertEquals(2, arcDiffs[0]);
}
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneDep.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneDep.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneDep.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneDep.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,10 @@
+package org.apache.cayenne.testdo.mt;
+
+import org.apache.cayenne.testdo.mt.auto._ClientMtTooneDep;
+
+/**
+ * A persistent class mapped as "MtTooneDep" Cayenne entity.
+ */
+public class ClientMtTooneDep extends _ClientMtTooneDep {
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneMaster.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneMaster.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneMaster.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/ClientMtTooneMaster.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,10 @@
+package org.apache.cayenne.testdo.mt;
+
+import org.apache.cayenne.testdo.mt.auto._ClientMtTooneMaster;
+
+/**
+ * A persistent class mapped as "MtTooneMaster" Cayenne entity.
+ */
+public class ClientMtTooneMaster extends _ClientMtTooneMaster {
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneDep.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneDep.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneDep.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneDep.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,7 @@
+package org.apache.cayenne.testdo.mt;
+
+import org.apache.cayenne.testdo.mt.auto._MtTooneDep;
+
+public class MtTooneDep extends _MtTooneDep {
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneMaster.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneMaster.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneMaster.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/MtTooneMaster.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,7 @@
+package org.apache.cayenne.testdo.mt;
+
+import org.apache.cayenne.testdo.mt.auto._MtTooneMaster;
+
+public class MtTooneMaster extends _MtTooneMaster {
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneDep.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneDep.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneDep.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneDep.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,33 @@
+package org.apache.cayenne.testdo.mt.auto;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.testdo.mt.ClientMtTooneMaster;
+
+/**
+ * A generated persistent class mapped as "MtTooneDep" 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 _ClientMtTooneDep extends PersistentObject {
+
+ public static final String TO_MASTER_PROPERTY = "toMaster";
+
+ protected ValueHolder toMaster;
+
+ public ClientMtTooneMaster getToMaster() {
+ if(objectContext != null) {
+ objectContext.prepareForAccess(this, "toMaster", true);
+ }
+
+ return (ClientMtTooneMaster) toMaster.getValue();
+ }
+ public void setToMaster(ClientMtTooneMaster toMaster) {
+ if(objectContext != null) {
+ objectContext.prepareForAccess(this, "toMaster", true);
+ }
+
+ this.toMaster.setValue(toMaster);
+ }
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneMaster.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneMaster.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneMaster.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_ClientMtTooneMaster.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,33 @@
+package org.apache.cayenne.testdo.mt.auto;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.testdo.mt.ClientMtTooneDep;
+
+/**
+ * A generated persistent class mapped as "MtTooneMaster" 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 _ClientMtTooneMaster extends PersistentObject {
+
+ public static final String TO_DEPENDENT_PROPERTY = "toDependent";
+
+ protected ValueHolder toDependent;
+
+ public ClientMtTooneDep getToDependent() {
+ if(objectContext != null) {
+ objectContext.prepareForAccess(this, "toDependent", true);
+ }
+
+ return (ClientMtTooneDep) toDependent.getValue();
+ }
+ public void setToDependent(ClientMtTooneDep toDependent) {
+ if(objectContext != null) {
+ objectContext.prepareForAccess(this, "toDependent", true);
+ }
+
+ this.toDependent.setValue(toDependent);
+ }
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneDep.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneDep.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneDep.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneDep.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,27 @@
+package org.apache.cayenne.testdo.mt.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.testdo.mt.MtTooneMaster;
+
+/**
+ * Class _MtTooneDep 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 _MtTooneDep extends CayenneDataObject {
+
+ public static final String TO_MASTER_PROPERTY = "toMaster";
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public void setToMaster(MtTooneMaster toMaster) {
+ setToOneTarget("toMaster", toMaster, true);
+ }
+
+ public MtTooneMaster getToMaster() {
+ return (MtTooneMaster)readProperty("toMaster");
+ }
+
+
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneMaster.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneMaster.java?rev=762115&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneMaster.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/mt/auto/_MtTooneMaster.java Sun Apr 5 16:44:11 2009
@@ -0,0 +1,27 @@
+package org.apache.cayenne.testdo.mt.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.testdo.mt.MtTooneDep;
+
+/**
+ * Class _MtTooneMaster 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 _MtTooneMaster extends CayenneDataObject {
+
+ public static final String TO_DEPENDENT_PROPERTY = "toDependent";
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public void setToDependent(MtTooneDep toDependent) {
+ setToOneTarget("toDependent", toDependent, true);
+ }
+
+ public MtTooneDep getToDependent() {
+ return (MtTooneDep)readProperty("toDependent");
+ }
+
+
+}
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=762115&r1=762114&r2=762115&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 Sun Apr 5 16:44:11 2009
@@ -70,6 +70,12 @@
<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
<db-attribute name="NUMERIC_COLUMN" type="INTEGER"/>
</db-entity>
+ <db-entity name="MT_TOONE_DEP">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="MT_TOONE_MASTER">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
<obj-entity name="MtDeleteCascade" className="org.apache.cayenne.testdo.mt.MtDeleteCascade" clientClassName="org.apache.cayenne.testdo.mt.ClientMtDeleteCascade" dbEntityName="MT_DELETE_CASCADE">
<obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
</obj-entity>
@@ -116,6 +122,10 @@
<obj-attribute name="blablacheck" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
<obj-attribute name="number" type="int" db-attribute-path="NUMERIC_COLUMN"/>
</obj-entity>
+ <obj-entity name="MtTooneDep" className="org.apache.cayenne.testdo.mt.MtTooneDep" clientClassName="org.apache.cayenne.testdo.mt.ClientMtTooneDep" dbEntityName="MT_TOONE_DEP">
+ </obj-entity>
+ <obj-entity name="MtTooneMaster" className="org.apache.cayenne.testdo.mt.MtTooneMaster" clientClassName="org.apache.cayenne.testdo.mt.ClientMtTooneMaster" dbEntityName="MT_TOONE_MASTER">
+ </obj-entity>
<db-relationship name="cascade" source="MT_DELETE_CASCADE" target="MT_DELETE_RULE" toMany="false">
<db-attribute-pair source="DELETE_RULE_ID" target="DELETE_RULE_ID"/>
</db-relationship>
@@ -170,6 +180,12 @@
<db-relationship name="joins" source="MT_TABLE5" target="MT_JOIN45" toMany="true">
<db-attribute-pair source="ID" target="TABLE5_ID"/>
</db-relationship>
+ <db-relationship name="toMaster" source="MT_TOONE_DEP" target="MT_TOONE_MASTER" toMany="false">
+ <db-attribute-pair source="ID" target="ID"/>
+ </db-relationship>
+ <db-relationship name="toDependent" source="MT_TOONE_MASTER" target="MT_TOONE_DEP" toDependentPK="true" toMany="false">
+ <db-attribute-pair source="ID" target="ID"/>
+ </db-relationship>
<obj-relationship name="cascade" source="MtDeleteCascade" target="MtDeleteRule" deleteRule="Cascade" db-relationship-path="cascade"/>
<obj-relationship name="deny" source="MtDeleteDeny" target="MtDeleteRule" deleteRule="Deny" db-relationship-path="deny"/>
<obj-relationship name="nullify" source="MtDeleteNullify" target="MtDeleteRule" deleteRule="Nullify" db-relationship-path="nullify"/>
@@ -186,6 +202,8 @@
<obj-relationship name="table2Array" source="MtTable3" target="MtTable2" deleteRule="Deny" db-relationship-path="table2Array"/>
<obj-relationship name="table5s" source="MtTable4" target="MtTable5" db-relationship-path="joins.toTable5"/>
<obj-relationship name="table4s" source="MtTable5" target="MtTable4" db-relationship-path="joins.toTable4"/>
+ <obj-relationship name="toMaster" source="MtTooneDep" target="MtTooneMaster" deleteRule="Nullify" db-relationship-path="toMaster"/>
+ <obj-relationship name="toDependent" source="MtTooneMaster" target="MtTooneDep" deleteRule="Cascade" db-relationship-path="toDependent"/>
<query name="AllMtTable1" factory="org.apache.cayenne.map.SelectQueryBuilder" root="obj-entity" root-name="MtTable1">
</query>
<query name="MtQueryWithLocalCache" factory="org.apache.cayenne.map.SelectQueryBuilder" root="obj-entity" root-name="MtTable1">