You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2006/12/15 06:50:50 UTC

svn commit: r487456 - in /incubator/openejb/trunk/openejb3: ./ container/openejb-core/ container/openejb-core/src/main/java/org/apache/openejb/core/cmp/ container/openejb-core/src/test/java/org/apache/openejb/ container/openejb-core/src/test/java/org/a...

Author: dain
Date: Thu Dec 14 21:50:48 2006
New Revision: 487456

URL: http://svn.apache.org/viewvc?view=rev&rev=487456
Log:
Fixed one-to-many cascade delete
Changed one-to-many relationships to be based on collections instead of maps
Added necessary dependencies now that specs are scope provided

Added:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java
Modified:
    incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapper.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapperFactory.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrFactoryImpl.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/JpaTest.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/MultiValuedCmrImpl.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SingleValuedCmrImpl.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/iTest.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/CmrFactory.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean_JPA.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ALocal.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean_JPA.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BLocal.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/jpa.mapping.xml
    incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/HsqldbTestDatabase.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToManyTests.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToOneTests.java
    incubator/openejb/trunk/openejb3/pom.xml

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml Thu Dec 14 21:50:48 2006
@@ -176,10 +176,18 @@
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-annotation_1.0_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-ejb_3.0_spec</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-interceptor_3.0_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-j2ee-connector_1.5_spec</artifactId>
     </dependency>
     <dependency>
@@ -193,6 +201,10 @@
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-j2ee-deployment_1.1_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jta_1.1_spec</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.xbean</groupId>

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java Thu Dec 14 21:50:48 2006
@@ -22,7 +22,6 @@
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.Container;
 import org.apache.openejb.ApplicationException;
-import org.apache.openejb.InvalidateReferenceException;
 import org.apache.openejb.ProxyInfo;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Enumerator;
@@ -357,6 +356,7 @@
 
     private void ejbRemove(EntityBean entityBean) throws RemoveException {
         if (entityBean == null) throw new NullPointerException("entityBean is null");
+        if (isDeleted(entityBean)) return;
 
         ThreadContext callContext = createThreadContext(entityBean);
         callContext.setCurrentOperation(Operations.OP_REMOVE);
@@ -378,6 +378,24 @@
         }
     }
 
+    private boolean isDeleted(EntityBean entityBean) {
+        try {
+            return entityBean.getClass().getField("deleted").getBoolean(entityBean);
+        } catch (NoSuchFieldException e) {
+            return false;
+        } catch (Exception e) {
+            throw new EJBException(e);
+        }
+    }
+
+    private void setDeleted(EntityBean entityBean, boolean deleted) {
+        try {
+            entityBean.getClass().getField("deleted").setBoolean(entityBean, deleted);
+        } catch (Exception e) {
+            throw new EJBException(e);
+        }
+    }
+
     private void ejbActivate(EntityBean entityBean) {
         if (entityBean == null) throw new NullPointerException("entityBean is null");
 
@@ -706,6 +724,8 @@
         txPolicy.beforeInvoke(null, txContext);
         try {
             CmpEngine cmpEngine = getCmpEngine(deploymentInfo.getDeploymentID());
+            EntityBean entityBean = (EntityBean) cmpEngine.loadBean(callContext, callContext.getPrimaryKey());
+            ejbRemove(entityBean);
             cmpEngine.removeBean(callContext);
         } catch (Throwable e) {// handle reflection exception
             txPolicy.handleSystemException(e, null, txContext);

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java Thu Dec 14 21:50:48 2006
@@ -43,6 +43,9 @@
         if (proxy == null) return null;
 
         EjbObjectProxyHandler handler = (EjbObjectProxyHandler) ProxyManager.getInvocationHandler(proxy);
+        if (handler.container == null) {
+            return null;
+        }
         if (!(handler.container instanceof CmpContainer)) {
             throw new IllegalArgumentException("Proxy is not connected to a CMP container but is conect to " + handler.container.getClass().getName());
         }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapper.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapper.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapper.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapper.java Thu Dec 14 21:50:48 2006
@@ -33,23 +33,23 @@
         type = addCmrMethod.getDeclaringClass();
     }
 
-    public Object addCmr(String property, Object pk, Object bean) {
+    public Object addCmr(String property, Object bean) {
         if (property == null) throw new NullPointerException("property is null");
         try {
-            Object oldValue = addCmrMethod.invoke(this.bean, property, pk, bean);
+            Object oldValue = addCmrMethod.invoke(this.bean, property, bean);
             return oldValue;
         } catch (Exception e) {
-            throw new EJBException("Error setting property " + property + " on entity bean of type " + type.getName());
+            throw new EJBException("Error setting property " + property + " on entity bean of type " + type.getName(), e);
         }
     }
 
-    public Object removeCmr(String property, Object pk, Object bean) {
+    public Object removeCmr(String property, Object bean) {
         if (property == null) throw new NullPointerException("property is null");
         try {
-            Object oldValue = removeCmrMethod.invoke(this.bean, property, pk, bean);
+            Object oldValue = removeCmrMethod.invoke(this.bean, property, bean);
             return oldValue;
         } catch (Exception e) {
-            throw new EJBException("Error setting property " + property + " on entity bean of type " + type.getName());
+            throw new EJBException("Error setting property " + property + " on entity bean of type " + type.getName(), e);
         }
     }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapperFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapperFactory.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapperFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmpWrapperFactory.java Thu Dec 14 21:50:48 2006
@@ -25,16 +25,16 @@
 
     public CmpWrapperFactory(Class relatedType) {
         try {
-            addCmrMethod = relatedType.getMethod("OpenEJB_addCmr", String.class, Object.class, Object.class);
+            addCmrMethod = relatedType.getMethod("OpenEJB_addCmr", String.class, Object.class);
         } catch (NoSuchMethodException e) {
             throw new IllegalArgumentException("EntityBean class " + relatedType.getName() +
-                    " does not contain the generated method OpenEJB_addCmr(String name, Object pk, Object bean) method");
+                    " does not contain the generated method OpenEJB_addCmr(String name, Object bean) method");
         }
         try {
-            removeCmrMethod = relatedType.getMethod("OpenEJB_removeCmr", String.class, Object.class, Object.class);
+            removeCmrMethod = relatedType.getMethod("OpenEJB_removeCmr", String.class, Object.class);
         } catch (NoSuchMethodException e) {
             throw new IllegalArgumentException("EntityBean class " + relatedType.getName() +
-                    " does not contain the generated method OpenEJB_removeCmr(String name, Object pk, Object bean) method");
+                    " does not contain the generated method OpenEJB_removeCmr(String name, Object bean) method");
         }
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrFactoryImpl.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrFactoryImpl.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrFactoryImpl.java Thu Dec 14 21:50:48 2006
@@ -29,7 +29,7 @@
         return new SingleValuedCmrImpl<Bean, Proxy>(source, sourceProperty, relatedType, relatedProperty);
     }
 
-    public <Bean extends EntityBean, Proxy extends EJBLocalObject, PK> MultiValuedCmr<Bean, Proxy, PK> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property) {
-        return new MultiValuedCmrImpl<Bean, Proxy, PK>(source, sourceProperty, relatedType, property);
+    public <Bean extends EntityBean, Proxy extends EJBLocalObject> MultiValuedCmr<Bean, Proxy> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property) {
+        return new MultiValuedCmrImpl<Bean, Proxy>(source, sourceProperty, relatedType, property);
     }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java Thu Dec 14 21:50:48 2006
@@ -27,15 +27,10 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Map;
+import java.util.Set;
+import java.util.Collections;
 
-/**
- *
- *
- * @version $Revision: 945 $ $Date: 2003-11-18 20:04:26 -0600 (Tue, 18 Nov 2003) $
- */
-public class CmrSet<Bean extends EntityBean, Proxy extends EJBLocalObject, PK> extends AbstractSet<Proxy> {
-    private final CoreDeploymentInfo sourceInfo;
+public class CmrSet<Bean extends EntityBean, Proxy extends EJBLocalObject> extends AbstractSet<Proxy> {
     private final EntityBean source;
     private final Class<? extends EntityBean> sourceType;
     private final String sourceProperty;
@@ -44,10 +39,10 @@
     private final Class<Bean> relatedType;
     private final String relatedProperty;
     private final CmpWrapperFactory relatedWrapperFactory;
-    private final Map<PK, Bean> relatedBeans;
+    private final CollectionRef<Bean> relatedBeanRef;
+    private Class relatedLocal;
 
-    public CmrSet(CoreDeploymentInfo sourceInfo, EntityBean source, String sourceProperty, CmpWrapperFactory sourceWrapperFactory, CoreDeploymentInfo relatedInfo, Class<Bean> relatedType, String relatedProperty, CmpWrapperFactory relatedWrapperFactory, Map<PK, Bean> relatedBeans) {
-        this.sourceInfo = sourceInfo;
+    public CmrSet(EntityBean source, String sourceProperty, CmpWrapperFactory sourceWrapperFactory, CoreDeploymentInfo relatedInfo, Class<Bean> relatedType, String relatedProperty, CmpWrapperFactory relatedWrapperFactory, CollectionRef<Bean> relatedBeanRef) {
         this.source = source;
         this.sourceProperty = sourceProperty;
         this.sourceWrapperFactory = sourceWrapperFactory;
@@ -55,80 +50,90 @@
         this.relatedType = relatedType;
         this.relatedProperty = relatedProperty;
         this.relatedWrapperFactory = relatedWrapperFactory;
-        this.relatedBeans = relatedBeans;
+        this.relatedBeanRef = relatedBeanRef;
         this.sourceType = source.getClass();
 
+        relatedLocal = relatedInfo.getLocalInterface();
     }
 
-    // todo should we support a close method?
-//    void invalidate() {
-//        context = null;
-//        slot = -1;
-//        relatedContainer = null;
-//        keys = null;
-//        relatedLocalInterface = null;
-//    }
-
     public boolean isEmpty() {
-        return relatedBeans.isEmpty();
+        return getRelatedBeans(false).isEmpty();
     }
 
     public int size() {
-        return relatedBeans.size();
+        return getRelatedBeans(false).size();
     }
 
     public boolean contains(Object o) {
-        if (relatedType.isInstance(o)) {
-            PK primaryKey = getPrimaryKey(o);
-            return relatedBeans.containsKey(primaryKey);
+        if (relatedLocal.isInstance(o)) {
+            Bean entity = getEntityBean((EJBLocalObject) o);
+            return entity != null && getRelatedBeans(false).contains(entity);
         }
         return false;
     }
 
+    public boolean addAll(Collection<? extends Proxy> c) {
+        Set entityBeans = getEntityBeans(c, relatedLocal);
+        boolean changed = false;
+        for (Iterator iterator = entityBeans.iterator(); iterator.hasNext();) {
+            Bean bean = (Bean) iterator.next();
+            changed = add(bean) || changed;
+        }
+        return changed;
+    }
+
     public boolean add(Proxy proxy) {
-        Object sourcePk = getSourcePk();
-        PK newPk = getPrimaryKey(proxy);
-        Bean newBean = getEntityBean(proxy);
-        boolean changed = relatedBeans.put(newPk, newBean) == null;
+        if (!relatedLocal.isInstance(proxy)) {
+            throw new IllegalArgumentException("Object is not an instance of " + relatedLocal.getName() +
+                                ": " + (proxy == null ? "null" : proxy.getClass().getName()));
+
+        }
+        Bean newEntity = getEntityBean(proxy);
+        if (newEntity == null) {
+            throw new IllegalArgumentException("Ejb has been deleted");
+        }
+
+        return add(newEntity);
+    }
+
+    private boolean add(Bean newEntity) {
+        boolean changed = getRelatedBeans(true).add(newEntity);
         if (changed) {
             // set the back reference in the new related bean
-            Object oldBackRef = getCmpWrapper(newBean).addCmr(relatedProperty, sourcePk, source);
-
-            // add the bean to our value map
-            relatedBeans.put(newPk, newBean);
+            Object oldBackRef = getCmpWrapper(newEntity).addCmr(relatedProperty, source);
 
             // if the new related beas was related to another bean, we need
             // to clear the back reference in that old bean
             if (oldBackRef != null) {
-                getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newPk, newBean);
+                getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newEntity);
             }
         }
         return changed;
     }
 
     public boolean remove(Object o) {
-        PK primaryKey = getPrimaryKey(o);
-        Bean oldBean = relatedBeans.remove(primaryKey);
-        if (oldBean != null) {
-            Object sourcePk = getSourcePk();
-            getCmpWrapper(oldBean).removeCmr(relatedProperty, sourcePk, source);
+        if (!relatedLocal.isInstance(o)) {
+            return false;
+        }
+
+        Bean entity = getEntityBean((EJBLocalObject) o);
+        boolean changed = entity != null && getRelatedBeans(false).remove(entity);
+        if (changed) {
+            getCmpWrapper(entity).removeCmr(relatedProperty, source);
         }
-        return oldBean != null;
+        return changed;
     }
 
     public boolean retainAll(Collection<?> c) {
-        Collection<PK> inputKeys = getPrimaryKeys(c);
+        Set entityBeans = getEntityBeans(c, null);
 
         boolean changed = false;
-        Object sourcePk = getSourcePk();
-        for (Iterator<Map.Entry<PK, Bean>> iterator = relatedBeans.entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry<PK, Bean> entry = iterator.next();
-            PK pk = entry.getKey();
-            Bean bean = entry.getValue();
-            if (!inputKeys.contains(pk)) {
-                changed = true;
+        for (Iterator<Bean> iterator = getRelatedBeans(false).iterator(); iterator.hasNext();) {
+            Bean entity = iterator.next();
+            if (!entityBeans.contains(entity)) {
                 iterator.remove();
-                getCmpWrapper(bean).removeCmr(relatedProperty, sourcePk, source);
+                getCmpWrapper(entity).removeCmr(relatedProperty, source);
+                changed = true;
             }
         }
         return changed;
@@ -137,10 +142,7 @@
     public Iterator<Proxy> iterator() {
         return new Iterator<Proxy>() {
             private Bean currentEntity;
-            private Object sourcePk = getSourcePk();
-
-            // todo we should drop the reference to the iterator when the set is invalidated
-            private Iterator<Bean> iterator = relatedBeans.values().iterator();
+            private Iterator<Bean> iterator = getRelatedBeans(true).iterator();
 
             public boolean hasNext() {
                 return iterator.hasNext();
@@ -153,20 +155,11 @@
 
             public void remove() {
                 iterator.remove();
-                getCmpWrapper(currentEntity).removeCmr(relatedProperty, sourcePk, source);
+                getCmpWrapper(currentEntity).removeCmr(relatedProperty, source);
             }
         };
     }
 
-    private Collection<PK> getPrimaryKeys(Collection c) {
-        Collection<PK> inputKeys = new HashSet<PK>(c.size());
-        for (Iterator iterator = c.iterator(); iterator.hasNext();) {
-            Proxy ejb = (Proxy) iterator.next();
-            inputKeys.add(getPrimaryKey(ejb));
-        }
-        return inputKeys;
-    }
-
     private Proxy getEjbProxy(Bean entity) throws EJBException {
         if (entity == null) return null;
 
@@ -181,18 +174,22 @@
         return bean;
     }
 
-    private PK getPrimaryKey(Object o) {
-        Proxy proxy = (Proxy) o;
-        return (PK) proxy.getPrimaryKey();
-    }
+    private static Set<Object> getEntityBeans(Collection<?> proxies, Class type) {
+        if (proxies == null) return null;
 
-    private Object getSourcePk() {
-        Object sourcePk = CmpUtil.getPrimaryKey(sourceInfo, source);
-        if (sourcePk == null) {
-            throw new IllegalStateException("CMR " + sourceProperty + " can not be modified on entity of type " +
-                    sourceInfo.getBeanClass().getName() + " because primary key has not been established yet.");
+        Set<Object> entities = new HashSet<Object>();
+        for (Object value : proxies) {
+            if (type != null && !type.isInstance(value)) {
+                throw new IllegalArgumentException("Object is not an instance of " + type.getName() +
+                                    ": " + (value == null ? "null" : value.getClass().getName()));
+            }
+            EntityBean entity = CmpUtil.getEntityBean((EJBLocalObject) value);
+            if (entity == null) {
+                throw new IllegalArgumentException("Entity has been deleted");
+            }
+            entities.add(entity);
         }
-        return sourcePk;
+        return entities;
     }
 
     private CmpWrapper getCmpWrapper(Object object) {
@@ -203,5 +200,16 @@
             return relatedWrapperFactory.createCmpEntityBean(object);
         }
         throw new IllegalArgumentException("Unknown cmp bean type " + object.getClass().getName());
+    }
+
+    private Collection<Bean> getRelatedBeans(boolean mustExist) {
+        Collection<Bean> relatedBeans = relatedBeanRef.get();
+        if (relatedBeans == null) {
+            if (mustExist) {
+                throw new IllegalStateException("Entity has been deleted therefore this cmr collection can no longer be modified");
+            }
+            relatedBeans = Collections.emptySet();
+        }
+        return relatedBeans;
     }
 }

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java?view=auto&rev=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java Thu Dec 14 21:50:48 2006
@@ -0,0 +1,32 @@
+/**
+ *
+ * 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.openejb.core.cmp.jpa;
+
+import java.util.Collection;
+
+public class CollectionRef<E> {
+    private Collection<E> collection;
+
+    public Collection<E> get() {
+        return collection;
+    }
+
+    public void set(Collection<E> collection) {
+        this.collection = collection;
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/JpaTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/JpaTest.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/JpaTest.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/JpaTest.java Thu Dec 14 21:50:48 2006
@@ -214,8 +214,8 @@
         beginTx();
         b = entityManager.find(BBean_JPA.class, 22);
         a = entityManager.find(ABean_JPA.class, 2);
-        a.OpenEJB_addCmr("b", 22, b);
-        b.OpenEJB_addCmr("a", 2, a);
+        a.OpenEJB_addCmr("b", b);
+        b.OpenEJB_addCmr("a", a);
         commitTx();
 
 //        dump();

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/MultiValuedCmrImpl.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/MultiValuedCmrImpl.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/MultiValuedCmrImpl.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/MultiValuedCmrImpl.java Thu Dec 14 21:50:48 2006
@@ -23,11 +23,9 @@
 
 import javax.ejb.EJBLocalObject;
 import javax.ejb.EntityBean;
-import java.util.Map;
 import java.util.Set;
 
-public class MultiValuedCmrImpl<Bean extends EntityBean, Proxy extends EJBLocalObject, PK> implements MultiValuedCmr<Bean, Proxy, PK> {
-    private final CoreDeploymentInfo sourceInfo;
+public class MultiValuedCmrImpl<Bean extends EntityBean, Proxy extends EJBLocalObject> implements MultiValuedCmr<Bean, Proxy> {
     private final EntityBean source;
     private final Class<? extends EntityBean> sourceType;
     private final String sourceProperty;
@@ -36,6 +34,7 @@
     private final CoreDeploymentInfo relatedInfo;
     private final CmpWrapperFactory sourceWrapperFactory;
     private final CmpWrapperFactory relatedWrapperFactory;
+    private final CollectionRef<Bean> collectionRef = new CollectionRef<Bean>();
 
     public MultiValuedCmrImpl(EntityBean source, String sourceProperty, Class<Bean> relatedType, String relatedProperty) {
         if (source == null) throw new NullPointerException("source is null");
@@ -48,57 +47,56 @@
         this.relatedProperty = relatedProperty;
         this.sourceType = source.getClass();
 
-        this.sourceInfo = CmpUtil.getDeploymentInfo(source.getClass());
         this.relatedInfo = CmpUtil.getDeploymentInfo(relatedType);
 
         sourceWrapperFactory = new CmpWrapperFactory(sourceType);
         relatedWrapperFactory = new CmpWrapperFactory(relatedType);
     }
 
-    public Set<Proxy> get(Map<PK, Bean> others) {
+    public Set<Proxy> get(Set<Bean> others) {
         if (others == null) throw new NullPointerException("others is null");
-        Set<Proxy> cmrSet = new CmrSet<Bean, Proxy, PK>(sourceInfo, source, sourceProperty, sourceWrapperFactory, relatedInfo, relatedType, relatedProperty, relatedWrapperFactory, others);
+        collectionRef.set(others);
+        Set<Proxy> cmrSet = new CmrSet<Bean, Proxy>(source, sourceProperty, sourceWrapperFactory, relatedInfo, relatedType, relatedProperty, relatedWrapperFactory, collectionRef);
         return cmrSet;
     }
 
-    public void set(Map<PK, Bean> relatedBeans, Set<Proxy> newProxies) {
-        Object sourcePk = getSourcePk();
-
+    public void set(Set<Bean> relatedBeans, Set<Proxy> newProxies) {
         // clear back reference in the old related beans
-        for (Bean oldBean : relatedBeans.values()) {
+        for (Bean oldBean : relatedBeans) {
             if (oldBean != null) {
-                getCmpWrapper(oldBean).removeCmr(relatedProperty, sourcePk, source);
+                getCmpWrapper(oldBean).removeCmr(relatedProperty, source);
             }
         }
         relatedBeans.clear();
 
         for (Proxy newProxy : newProxies) {
             Bean newBean = (Bean) CmpUtil.getEntityBean(newProxy);
-            PK newPk = (PK) newProxy.getPrimaryKey();
 
             if (newProxy != null) {
                 // set the back reference in the new related bean
-                Object oldBackRef = getCmpWrapper(newBean).addCmr(relatedProperty, sourcePk, source);
+                Object oldBackRef = getCmpWrapper(newBean).addCmr(relatedProperty, source);
 
                 // add the bean to our value map
-                relatedBeans.put(newPk, newBean);
+                relatedBeans.add(newBean);
 
                 // if the new related beas was related to another bean, we need
                 // to clear the back reference in that old bean
                 if (oldBackRef != null) {
-                    getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newPk, newBean);
+                    getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newBean);
                 }
             }
         }
     }
 
-    private Object getSourcePk() {
-        Object sourcePk = CmpUtil.getPrimaryKey(sourceInfo, source);
-        if (sourcePk == null) {
-            throw new IllegalStateException("CMR " + sourceProperty + " can not be modified on entity of type " +
-                    sourceInfo.getBeanClass().getName() + " because primary key has not been established yet.");
+    public void deleted(Set<Bean> relatedBeans) {
+        collectionRef.set(null);
+
+        // clear back reference in the old related beans
+        for (Bean oldBean : relatedBeans) {
+            if (oldBean != null) {
+                getCmpWrapper(oldBean).removeCmr(relatedProperty, source);
+            }
         }
-        return sourcePk;
     }
 
     private CmpWrapper getCmpWrapper(Object object) {
@@ -110,4 +108,5 @@
         }
         throw new IllegalArgumentException("Unknown cmp bean type " + object.getClass().getName());
     }
+
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SingleValuedCmrImpl.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SingleValuedCmrImpl.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SingleValuedCmrImpl.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SingleValuedCmrImpl.java Thu Dec 14 21:50:48 2006
@@ -26,7 +26,6 @@
 import javax.ejb.EntityBean;
 
 public class SingleValuedCmrImpl<Bean extends EntityBean, Proxy extends EJBLocalObject> implements SingleValuedCmr<Bean, Proxy> {
-    private final CoreDeploymentInfo sourceInfo;
     private final EntityBean source;
     private final Class<? extends EntityBean> sourceType;
     private final String sourceProperty;
@@ -47,7 +46,6 @@
         this.relatedProperty = relatedProperty;
         this.sourceType = source.getClass();
 
-        this.sourceInfo = CmpUtil.getDeploymentInfo(source.getClass());
         this.relatedInfo = CmpUtil.getDeploymentInfo(relatedType);
 
         sourceWrapperFactory = new CmpWrapperFactory(sourceType);
@@ -62,34 +60,24 @@
     }
 
     public Bean set(Bean oldBean, Proxy newValue) throws EJBException {
-        Object sourcePk = getSourcePk();
         Bean newBean = (Bean) CmpUtil.getEntityBean(newValue);
 
         // clear back reference in the old related bean
         if (oldBean != null) {
-            getCmpWrapper(oldBean).removeCmr(relatedProperty, sourcePk, source);
+            getCmpWrapper(oldBean).removeCmr(relatedProperty, source);
         }
 
         if (newValue != null) {
             // set the back reference in the new related bean
-            Object oldBackRef = getCmpWrapper(newBean).addCmr(relatedProperty, sourcePk, source);
+            Object oldBackRef = getCmpWrapper(newBean).addCmr(relatedProperty, source);
 
             // if the new related beas was related to another bean, we need
             // to clear the back reference in that old bean
             if (oldBackRef != null) {
-                getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newValue.getPrimaryKey(), newBean);
+                getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newBean);
             }
         }
         return newBean;
-    }
-
-    private Object getSourcePk() {
-        Object sourcePk = CmpUtil.getPrimaryKey(sourceInfo, source);
-        if (sourcePk == null) {
-            throw new IllegalStateException("CMR " + sourceProperty + " can not be modified on entity of type " +
-                    sourceInfo.getBeanClass().getName() + " because primary key has not been established yet.");
-        }
-        return sourcePk;
     }
 
     private CmpWrapper getCmpWrapper(Object object) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/iTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/iTest.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/iTest.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/iTest.java Thu Dec 14 21:50:48 2006
@@ -65,10 +65,10 @@
 
     public static Test suite() {
         TestSuite suite = new iTest();
-//        suite.addTest(StatelessLocalTestSuite.suite());
-//        suite.addTest(StatefulLocalTestSuite.suite());
-//        suite.addTest(BmpLocalTestSuite.suite());
-//        suite.addTest(CmpLocalTestSuite.suite());
+        suite.addTest(StatelessLocalTestSuite.suite());
+        suite.addTest(StatefulLocalTestSuite.suite());
+        suite.addTest(BmpLocalTestSuite.suite());
+        suite.addTest(CmpLocalTestSuite.suite());
         suite.addTest(Cmp2TestSuite.suite());
         return suite;
     }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/CmrFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/CmrFactory.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/CmrFactory.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/CmrFactory.java Thu Dec 14 21:50:48 2006
@@ -34,7 +34,7 @@
                         return null;
                     }
 
-                    public <Bean extends EntityBean, Proxy extends EJBLocalObject, PK> MultiValuedCmr<Bean, Proxy, PK> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property) {
+                    public <Bean extends EntityBean, Proxy extends EJBLocalObject> MultiValuedCmr<Bean, Proxy> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property) {
                         return null;
                     }
                 };
@@ -44,5 +44,5 @@
 
     <Bean extends EntityBean, Proxy extends EJBLocalObject> SingleValuedCmr<Bean, Proxy> createSingleValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property);
 
-    <Bean extends EntityBean, Proxy extends EJBLocalObject, PK> MultiValuedCmr<Bean, Proxy, PK> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property);
+    <Bean extends EntityBean, Proxy extends EJBLocalObject> MultiValuedCmr<Bean, Proxy> createMultiValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String property);
 }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java Thu Dec 14 21:50:48 2006
@@ -19,11 +19,12 @@
 
 import javax.ejb.EJBLocalObject;
 import javax.ejb.EntityBean;
-import java.util.Map;
 import java.util.Set;
 
-public interface MultiValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject, PK> {
-    Set<Proxy> get(Map<PK, Bean> others);
+public interface MultiValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject> {
+    Set<Proxy> get(Set<Bean> others);
 
-    void set(Map<PK, Bean> oldValue, Set<Proxy> newValue);
+    void set(Set<Bean> oldValue, Set<Proxy> newValue);
+
+    void deleted(Set<Bean> relatedBeans);
 }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean.java Thu Dec 14 21:50:48 2006
@@ -44,6 +44,9 @@
     public abstract Set<BLocal> getB();
     public abstract void setB(Set<BLocal> bSet);
 
+    public abstract Set<BLocal> getBNonCascade();
+    public abstract void setBNonCascade(Set<BLocal> bNonCascade);
+
     public Integer ejbCreate(Integer field1)  throws CreateException {
         setField1(field1);
         return null;

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean_JPA.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ABean_JPA.java Thu Dec 14 21:50:48 2006
@@ -17,20 +17,21 @@
  */
 package org.apache.openejb.test.entity.cmr.onetomany;
 
-import org.apache.openejb.test.entity.MultiValuedCmr;
 import org.apache.openejb.test.entity.CmrFactory;
+import org.apache.openejb.test.entity.MultiValuedCmr;
 
+import java.util.HashSet;
 import java.util.Set;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
 
 public class ABean_JPA extends ABean {
     public static Object deploymentInfo;
+    public transient boolean deleted;
     public Integer field1;
     private String field2;
-    private Map<Integer,BBean_JPA> b = new HashMap<Integer, BBean_JPA>();
-    private MultiValuedCmr<BBean_JPA, BLocal, Integer> bCmr = CmrFactory.cmrFactory.createMultiValuedCmr(this, "b", BBean_JPA.class, "a");
+    private Set<BBean_JPA> b = new HashSet<BBean_JPA>();
+    private MultiValuedCmr<BBean_JPA, BLocal> bCmr = CmrFactory.cmrFactory.createMultiValuedCmr(this, "b", BBean_JPA.class, "a");
+    private Set<BBean_JPA> bNonCascade = new HashSet<BBean_JPA>();
+    private MultiValuedCmr<BBean_JPA, BLocal> bNonCascadeCmr = CmrFactory.cmrFactory.createMultiValuedCmr(this, "bNonCascade", BBean_JPA.class, "aNonCascade");
 
     public Integer getField1() {
         return field1;
@@ -64,23 +65,43 @@
         bCmr.set(this.b, b);
     }
 
+    public Set<BLocal> getBNonCascade() {
+        return bNonCascadeCmr.get(bNonCascade);
+    }
+
+    public void setBNonCascade(Set<BLocal> bNonCascade) {
+        bNonCascadeCmr.set(this.bNonCascade, bNonCascade);
+    }
+
     public void OpenEJB_deleted() {
-        bCmr.set(b, Collections.<BLocal>emptySet());
+        if (deleted) return;
+        deleted = true;
+
+        bCmr.deleted(b);
+        bNonCascadeCmr.deleted(bNonCascade);
     }
 
-    public Object OpenEJB_addCmr(String name, Object pk, Object bean) {
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
         Object oldValue = null;
         if ("b".equals(name)) {
-            b.put((Integer)pk, (BBean_JPA) bean);
+            b.add((BBean_JPA) bean);
+        } else if ("bNonCascade".equals(name)) {
+            bNonCascade.add((BBean_JPA) bean);
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }
         return oldValue;
     }
 
-    public void OpenEJB_removeCmr(String name, Object pk, Object value) {
+    public void OpenEJB_removeCmr(String name, Object value) {
+        if (deleted) return;
+
         if ("b".equals(name)) {
-            b.remove(pk);
+            b.remove(value);
+        } else if ("bNonCascade".equals(name)) {
+            bNonCascade.remove(value);
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ALocal.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ALocal.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ALocal.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/ALocal.java Thu Dec 14 21:50:48 2006
@@ -36,4 +36,6 @@
     public Set<BLocal> getB();
     public void setB(Set<BLocal> bSet);
 
+    public Set<BLocal> getBNonCascade();
+    public void setBNonCascade(Set<BLocal> bNonCascade);
 }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean.java Thu Dec 14 21:50:48 2006
@@ -47,6 +47,9 @@
     // CMR
     public abstract ALocal getA();
     public abstract void setA(ALocal a);
+
+    public abstract ALocal getANonCascade();
+    public abstract void setANonCascade(ALocal aNonCascade);
     
     public Integer ejbCreate(Integer field1)  throws CreateException {
         setField1(field1);

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean_JPA.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BBean_JPA.java Thu Dec 14 21:50:48 2006
@@ -22,12 +22,15 @@
 
 public class BBean_JPA extends BBean {
     public static Object deploymentInfo;
+    public transient boolean deleted;
     public Integer field1;
     private String field2;
     private Integer field3;
     private String field4;
     private ABean_JPA a;
     private SingleValuedCmr<ABean_JPA, ALocal> aCmr = CmrFactory.cmrFactory.createSingleValuedCmr(this, "a", ABean_JPA.class, "b");
+    private ABean_JPA aNonCascade;
+    private SingleValuedCmr<ABean_JPA, ALocal> aNonCascadeCmr = CmrFactory.cmrFactory.createSingleValuedCmr(this, "aNonCascade", ABean_JPA.class, "bNonCascade");
 
     public Integer getField1() {
         return field1;
@@ -65,28 +68,49 @@
         return aCmr.get(a);
     }
 
-    public void OpenEJB_deleted() {
-        a = aCmr.set(a, null);
-    }
-
     public void setA(ALocal a) {
         this.a = aCmr.set(this.a, a);
     }
 
-    public Object OpenEJB_addCmr(String name, Object pk, Object bean) {
+    public ALocal getANonCascade() {
+        return aNonCascadeCmr.get(aNonCascade);
+    }
+
+    public void setANonCascade(ALocal aNonCascade) {
+        this.aNonCascade = aNonCascadeCmr.set(this.aNonCascade, aNonCascade);
+    }
+
+    public void OpenEJB_deleted() {
+        if (deleted) return;
+        deleted = true;
+
+        aCmr.set(a, null);
+        aNonCascadeCmr.set(aNonCascade, null);
+    }
+
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
         Object oldValue;
         if ("a".equals(name)) {
             oldValue = a;
             a = (ABean_JPA) bean;
+        } else if ("aNonCascade".equals(name)) {
+            oldValue = aNonCascade;
+            aNonCascade = (ABean_JPA) bean;
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }
         return oldValue;
     }
 
-    public void OpenEJB_removeCmr(String name, Object pk, Object bean) {
+    public void OpenEJB_removeCmr(String name, Object bean) {
+        if (deleted) return;
+
         if ("a".equals(name)) {
             a = null;
+        } else if ("aNonCascade".equals(name)) {
+            aNonCascade = null;
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BLocal.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BLocal.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BLocal.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetomany/BLocal.java Thu Dec 14 21:50:48 2006
@@ -40,4 +40,7 @@
     // CMR
     public ALocal getA();
     public void setA(ALocal a);
+
+    public ALocal getANonCascade();
+    public void setANonCascade(ALocal aNonCascade);    
 }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java Thu Dec 14 21:50:48 2006
@@ -22,6 +22,7 @@
 
 public class ABean_JPA extends ABean {
     public static Object deploymentInfo;
+    public transient boolean deleted;
     public Integer field1;
     private String field2;
     private BBean_JPA b;
@@ -52,10 +53,15 @@
     }
 
     public void OpenEJB_deleted() {
-        b = bCmr.set(b, null);
+        if (deleted) return;
+        deleted = true;
+
+        bCmr.set(b, null);
     }
 
-    public Object OpenEJB_addCmr(String name, Object pk, Object bean) {
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
         Object oldValue;
         if ("b".equals(name)) {
             oldValue = b;
@@ -66,7 +72,9 @@
         return oldValue;
     }
 
-    public void OpenEJB_removeCmr(String name, Object pk, Object bean) {
+    public void OpenEJB_removeCmr(String name, Object bean) {
+        if (deleted) return;
+
         if ("b".equals(name)) {
             b = null;
         } else {

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java Thu Dec 14 21:50:48 2006
@@ -22,6 +22,7 @@
 
 public class BBean_JPA extends BBean {
     public static Object deploymentInfo;
+    public transient boolean deleted;
     public Integer field1;
     private String field2;
     private Integer field3;
@@ -65,15 +66,20 @@
         return aCmr.get(a);
     }
 
-    public void OpenEJB_deleted() {
-        a = aCmr.set(a, null);
-    }
-
     public void setA(ALocal a) {
         this.a = aCmr.set(this.a, a);
     }
 
-    public Object OpenEJB_addCmr(String name, Object pk, Object bean) {
+    public void OpenEJB_deleted() {
+        if (deleted) return;
+        deleted = true;
+
+        aCmr.set(a, null);
+    }
+
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
         Object oldValue;
         if ("a".equals(name)) {
             oldValue = a;
@@ -84,7 +90,9 @@
         return oldValue;
     }
 
-    public void OpenEJB_removeCmr(String name, Object pk, Object bean) {
+    public void OpenEJB_removeCmr(String name, Object bean) {
+        if (deleted) return;
+
         if ("a".equals(name)) {
             a = null;
         } else {

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml Thu Dec 14 21:50:48 2006
@@ -1827,6 +1827,7 @@
                 <cmr-field>
                     <cmr-field-name>b</cmr-field-name>
                 </cmr-field>
+                <cascade-delete/>
             </ejb-relationship-role>
             <ejb-relationship-role>
                 <multiplicity>Many</multiplicity>
@@ -1835,6 +1836,26 @@
                 </relationship-role-source>
                 <cmr-field>
                     <cmr-field-name>a</cmr-field-name>
+                </cmr-field>
+            </ejb-relationship-role>
+        </ejb-relation>
+        <ejb-relation>
+            <ejb-relationship-role>
+                <multiplicity>One</multiplicity>
+                <relationship-role-source>
+                    <ejb-name>OneToManyA</ejb-name>
+                </relationship-role-source>
+                <cmr-field>
+                    <cmr-field-name>bNonCascade</cmr-field-name>
+                </cmr-field>
+            </ejb-relationship-role>
+            <ejb-relationship-role>
+                <multiplicity>Many</multiplicity>
+                <relationship-role-source>
+                    <ejb-name>OneToManyB</ejb-name>
+                </relationship-role-source>
+                <cmr-field>
+                    <cmr-field-name>aNonCascade</cmr-field-name>
                 </cmr-field>
             </ejb-relationship-role>
         </ejb-relation>

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/jpa.mapping.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/jpa.mapping.xml?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/jpa.mapping.xml (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/jpa.mapping.xml Thu Dec 14 21:50:48 2006
@@ -312,8 +312,11 @@
         <column name="A2"/>
       </basic>
       <one-to-many name="b" mapped-by="a">
-        <map-key name="field1"/>
+        <cascade>
+          <cascade-all/>
+        </cascade>
       </one-to-many>
+      <one-to-many name="bNonCascade" mapped-by="aNonCascade"/>
     </attributes>
   </entity>
 
@@ -334,9 +337,9 @@
       </basic>
       <many-to-one name="a">
         <join-column name="FKA1"/>
-        <cascade>
-          <cascade-all/>
-        </cascade>
+      </many-to-one>
+      <many-to-one name="aNonCascade">
+        <join-column name="FKA_NonCascade"/>
       </many-to-one>
     </attributes>
   </entity>

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/HsqldbTestDatabase.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/HsqldbTestDatabase.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/HsqldbTestDatabase.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/HsqldbTestDatabase.java Thu Dec 14 21:50:48 2006
@@ -46,7 +46,7 @@
     // OneToMany
     private static final String CREATE_ONE_TO_MANY_A = "CREATE TABLE OneToManyA(A1 INTEGER, A2 VARCHAR(50))";
     private static final String DROP_ONE_TO_MANY_A = "DROP TABLE OneToManyA";
-    private static final String CREATE_ONE_TO_MANY_B = "CREATE TABLE OneToManyB(B1 INTEGER, B2 VARCHAR(50), B3 INTEGER, B4 VARCHAR(50), FKA1 INTEGER)";
+    private static final String CREATE_ONE_TO_MANY_B = "CREATE TABLE OneToManyB(B1 INTEGER, B2 VARCHAR(50), B3 INTEGER, B4 VARCHAR(50), FKA1 INTEGER, FKA_NonCascade INTEGER)";
     private static final String DROP_ONE_TO_MANY_B = "DROP TABLE OneToManyB";
 
     // CmrMapping

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToManyTests.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToManyTests.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToManyTests.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToManyTests.java Thu Dec 14 21:50:48 2006
@@ -90,7 +90,7 @@
         }
     }
 
-    public void testASetBDropExisting() throws Exception {
+    public void test02_ASetBDropExisting() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -102,7 +102,7 @@
         assertUnlinked(1);
     }
 
-    public void testBSetADropExisting() throws Exception {
+    public void test03_BSetADropExisting() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -118,7 +118,7 @@
     }
 
 
-    public void testASetBNewAB() throws Exception {
+    public void test04_ASetBNewAB() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -134,7 +134,7 @@
         assertLinked(2, 22);
     }
 
-    public void testBSetANewAB() throws Exception {
+    public void test05_BSetANewAB() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -147,7 +147,7 @@
         assertLinked(2, 22);
     }
 
-    public void testASetBExistingBNewA() throws Exception {
+    public void test06_ASetBExistingBNewA() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -162,7 +162,7 @@
         assertLinked(2, 11);
     }
 
-    public void testBSetAExistingBNewA() throws Exception {
+    public void test07_BSetAExistingBNewA() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -176,7 +176,7 @@
         assertLinked(2, 11);
     }
 
-    public void testASetBExistingANewB() throws Exception {
+    public void test08_ASetBExistingANewB() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -190,7 +190,7 @@
         assertLinked(1, 11, 22, 33);
     }
 
-    public void testBSetAExistingANewB() throws Exception {
+    public void test09_BSetAExistingANewB() throws Exception {
         resetDB();
         beginTransaction();
         try {
@@ -204,28 +204,21 @@
         assertLinked(1, 11, 22, 33);
     }
 
-    public void testRemoveRelationships() throws Exception {
+    public void test10_RemoveRelationships() throws Exception {
         resetDB();
         beginTransaction();
         try {
-            ALocal a = findA(1);
-            a.remove();
+            BLocal b = findB(11);
+            ALocal a = b.getA();
+            Set<BLocal> bs = a.getB();
+            assertTrue(bs.contains(b));
+            b.remove();
+            assertFalse(bs.contains(b));
         } finally {
             completeTransaction();
         }
-
-        Connection c = ds.getConnection();
-        Statement s = c.createStatement();
-        ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM OneToManyB");
-        assertTrue(rs.next());
-        assertEquals(2, rs.getInt(1));
-        rs.close();
-        rs = s.executeQuery("SELECT COUNT(*) FROM OneToManyB WHERE fka1 = 1");
-        assertTrue(rs.next());
-        assertEquals(0, rs.getInt(1));
-        rs.close();
-        s.close();
-        c.close();
+        assertLinked(1, 22);
+        assertUnlinked(2);
     }
 
     // uncomment when cmp to cmr is supported
@@ -259,33 +252,56 @@
         }
     }
 
-    // todo cascade delete isn't working
-    public void TODO_testCascadeDelete() throws Exception {
+    public void test11_Delete() throws Exception {
         resetDB();
 
         beginTransaction();
         try {
             ALocal a = findA(1);
+            a.setB(new HashSet<BLocal>());
+            Set<BLocal> bs = a.getBNonCascade();
+            Set<BLocal> bsCopy = new HashSet<BLocal>(bs);
+            assertFalse(bs.isEmpty());
             a.remove();
+            assertTrue(bs.isEmpty());
+            for (BLocal bLocal : bsCopy) {
+                assertNull(bLocal.getANonCascade());
+            }
         } finally {
             completeTransaction();
         }
-        System.out.println();
         Connection c = ds.getConnection();
         Statement s = c.createStatement();
         ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM OneToManyB");
         assertTrue(rs.next());
-        assertEquals(0, rs.getInt(1));
+        assertEquals(2, rs.getInt(1));
         rs.close();
         s.close();
         c.close();
     }
 
-//    private ALocal createA(int aPk) throws CreateException {
-//        ALocal a = ahome.create(new Integer(aPk));
-//        a.setField2("value" + aPk);
-//        return a;
-//    }
+    public void test12_CascadeDelete() throws Exception {
+        resetDB();
+
+        beginTransaction();
+        try {
+            ALocal a = findA(1);
+            Set<BLocal> bs = a.getB();
+            assertFalse(bs.isEmpty());
+            a.remove();
+            assertTrue(bs.isEmpty());
+        } finally {
+            completeTransaction();
+        }
+        Connection c = ds.getConnection();
+        Statement s = c.createStatement();
+        ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM OneToManyB");
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt(1));
+        rs.close();
+        s.close();
+        c.close();
+    }
 
     private ALocal findA(int aPk) throws FinderException {
         return ahome.findByPrimaryKey(new Integer(aPk));
@@ -348,8 +364,8 @@
 
             statement.execute("INSERT INTO OneToManyA(A1, A2) VALUES(1, 'value1')");
             statement.execute("INSERT INTO OneToManyA(A1, A2) VALUES(2, 'value2')");
-            statement.execute("INSERT INTO OneToManyB(B1, B2, FKA1) VALUES(11, 'value11', 1)");
-            statement.execute("INSERT INTO OneToManyB(B1, B2, FKA1) VALUES(22, 'value22', 1)");
+            statement.execute("INSERT INTO OneToManyB(B1, B2, FKA1, FKA_NonCascade) VALUES(11, 'value11', 1, 1)");
+            statement.execute("INSERT INTO OneToManyB(B1, B2, FKA1, FKA_NonCascade) VALUES(22, 'value22', 1, 1)");
         } finally {
             close(statement);
             close(connection);

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToOneTests.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToOneTests.java?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToOneTests.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmr/OneToOneTests.java Thu Dec 14 21:50:48 2006
@@ -17,21 +17,16 @@
 package org.apache.openejb.test.entity.cmr;
 
 
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-
-
-import org.apache.openejb.test.entity.cmr.onetoone.ALocalHome;
 import org.apache.openejb.test.entity.cmr.onetoone.ALocal;
-import org.apache.openejb.test.entity.cmr.onetoone.BLocalHome;
+import org.apache.openejb.test.entity.cmr.onetoone.ALocalHome;
 import org.apache.openejb.test.entity.cmr.onetoone.BLocal;
+import org.apache.openejb.test.entity.cmr.onetoone.BLocalHome;
 
-import javax.ejb.FinderException;
 import javax.ejb.CreateException;
-import javax.sql.DataSource;
+import javax.ejb.FinderException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
 
 /**
  *

Modified: incubator/openejb/trunk/openejb3/pom.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/pom.xml?view=diff&rev=487456&r1=487455&r2=487456
==============================================================================
--- incubator/openejb/trunk/openejb3/pom.xml (original)
+++ incubator/openejb/trunk/openejb3/pom.xml Thu Dec 14 21:50:48 2006
@@ -668,6 +668,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geronimo.specs</groupId>
+        <artifactId>geronimo-annotation_1.0_spec</artifactId>
+        <version>1.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geronimo.specs</groupId>
         <artifactId>geronimo-ejb_3.0_spec</artifactId>
         <version>1.0-SNAPSHOT</version>
       </dependency>
@@ -682,6 +687,11 @@
           </exclusion>
         </exclusions>
       </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-interceptor_3.0_spec</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
       <dependency>
         <groupId>org.apache.geronimo.specs</groupId>
         <artifactId>geronimo-j2ee-deployment_1.1_spec</artifactId>