You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/04/29 21:08:11 UTC

svn commit: r769879 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/

Author: faywang
Date: Wed Apr 29 19:08:11 2009
New Revision: 769879

URL: http://svn.apache.org/viewvc?rev=769879&view=rev
Log:
OPENJPA-1053: fix update by setting an embeddable which contains a cascade delete relation with another entity.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java   (with props)
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=769879&r1=769878&r2=769879&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Wed Apr 29 19:08:11 2009
@@ -2658,8 +2658,11 @@
 
         // ACT_CASCADE
         if ((action & OpCallbacks.ACT_RUN) == 0) {
-            if (sm != null)
-                sm.cascadeDelete(call);
+            if (sm != null) {
+                if (!sm.isEmbedded() || !sm.getDereferencedEmbedDependent()) {
+                    sm.cascadeDelete(call);
+                }
+            }
             else
                 cascadeTransient(OpCallbacks.OP_DELETE, obj, call, "delete");
             return;
@@ -2669,8 +2672,11 @@
         if (sm != null) {
             if (sm.isDetached())
                 throw newDetachedException(obj, "delete");
-            if ((action & OpCallbacks.ACT_CASCADE) != 0)
-                sm.cascadeDelete(call);
+            if ((action & OpCallbacks.ACT_CASCADE) != 0) {
+                if (!sm.isEmbedded() || !sm.getDereferencedEmbedDependent()) {
+                    sm.cascadeDelete(call);
+                }
+            }
             sm.delete();
         } else if (assertPersistenceCapable(obj).pcIsDetached() == Boolean.TRUE)
             throw newDetachedException(obj, "delete");

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java?rev=769879&r1=769878&r2=769879&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java Wed Apr 29 19:08:11 2009
@@ -302,8 +302,11 @@
             // immediate cascade works on field value; dependent deref
             // works on external value
             if ((immediate || fmd.isEmbeddedPC())
-                && fmd.getCascadeDelete() == ValueMetaData.CASCADE_IMMEDIATE)
+                && fmd.getCascadeDelete() == ValueMetaData.CASCADE_IMMEDIATE) {
+                if (fmd.isEmbeddedPC())
+                    dereferenceEmbedDependent(_sm);
                 delete(fmd, objval, call);
+            }
             else if (fmd.getCascadeDelete() == ValueMetaData.CASCADE_AUTO)
                 dereferenceDependent(fmd.getExternalValue(objval, _broker));
             return;
@@ -413,7 +416,11 @@
         if (sm != null)
             sm.setDereferencedDependent(true, true);
     }
-
+    
+    void dereferenceEmbedDependent(StateManagerImpl sm) {
+    	sm.setDereferencedEmbedDependent(true);
+    }
+    
     /**
      * Recursively invoke the broker to gather cascade-refresh objects in
      * the current field into the given set. This method is only called

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=769879&r1=769878&r2=769879&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Apr 29 19:08:11 2009
@@ -107,6 +107,7 @@
     private static final int FLAG_VERSION_CHECK = 2 << 14;
     private static final int FLAG_VERSION_UPDATE = 2 << 15;
     private static final int FLAG_DETACHING = 2 << 16;
+    private static final int FLAG_EMBED_DEREF = 2 << 17;
 
     private static final Localizer _loc = Localizer.forPackage
         (StateManagerImpl.class);
@@ -1300,6 +1301,18 @@
                 _broker.addDereferencedDependent(this);
         }
     }
+    
+    void setDereferencedEmbedDependent(boolean deref) {
+        if (!deref && (_flags & FLAG_EMBED_DEREF) > 0) {
+            _flags &= ~FLAG_EMBED_DEREF;
+        } else if (deref && (_flags & FLAG_EMBED_DEREF) == 0) {
+            _flags |= FLAG_EMBED_DEREF;
+        }
+    }
+    
+    public boolean getDereferencedEmbedDependent() {
+        return ((_flags |= FLAG_EMBED_DEREF) == 0 ? false : true);
+    }
 
     ///////////
     // Locking

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java?rev=769879&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java Wed Apr 29 19:08:11 2009
@@ -0,0 +1,67 @@
+/*
+ * 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.openjpa.persistence.embed;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embeddable;
+import javax.persistence.FetchType;
+import javax.persistence.OneToOne;
+
+@Embeddable 
+public class Embed_MappedToOneCascadeDelete {
+    protected String name1;
+    protected String name2;
+    protected String name3;
+    
+    @OneToOne(mappedBy="entityA", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+    protected EntityB2 bm;
+    
+    
+    public String getName1() {
+        return name1;
+    }
+    
+    public void setName1(String name1) {
+        this.name1 = name1;
+    }
+    
+    public String getName2() {
+        return name2;
+    }
+    
+    public void setName2(String name2) {
+        this.name2 = name2;
+    }
+    
+    public String getName3() {
+        return name3;
+    }
+    
+    public void setName3(String name3) {
+        this.name3 = name3;
+    }
+    
+    public void setMappedEntityB(EntityB2 bm) {
+        this.bm = bm;
+    }
+    
+    public EntityB2 getMappedEntityB() {
+        return bm;
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Embed_MappedToOneCascadeDelete.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java?rev=769879&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java Wed Apr 29 19:08:11 2009
@@ -0,0 +1,77 @@
+/*
+ * 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.openjpa.persistence.embed;
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="TB11A")
+public class EntityA_Embed_MappedToOneCascadeDelete implements Serializable {
+    @Id
+    Integer id;
+
+    @Column(length=30)
+    String name;
+    
+    @Basic(fetch=FetchType.LAZY)
+    int age;
+
+    @Embedded
+    protected Embed_MappedToOneCascadeDelete embed;
+    
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Embed_MappedToOneCascadeDelete getEmbed() {
+        return embed;
+    }
+    
+    public void setEmbed(Embed_MappedToOneCascadeDelete embed) {
+        this.embed = embed;
+    }
+}
+

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityA_Embed_MappedToOneCascadeDelete.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java?rev=769879&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java Wed Apr 29 19:08:11 2009
@@ -0,0 +1,65 @@
+/*
+ * 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.openjpa.persistence.embed;
+import java.io.Serializable;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+public class EntityB2 implements Serializable {
+
+    @Id
+    int id;
+
+    @Column(length=30)
+    String name;
+    
+    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+    EntityA_Embed_MappedToOneCascadeDelete entityA;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public EntityA_Embed_MappedToOneCascadeDelete getEntityA() {
+        return entityA;
+    }
+
+    public void setEntityA(EntityA_Embed_MappedToOneCascadeDelete entityA) {
+        this.entityA = entityA;
+    }
+}
+

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EntityB2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java?rev=769879&r1=769878&r2=769879&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java Wed Apr 29 19:08:11 2009
@@ -79,7 +79,9 @@
             Employee3.class, EmployeeName3.class, Item1.class, Item2.class,
             Item3.class, Company1.class, Company2.class, Division.class, 
             VicePresident.class, EntityA_Embed_MappedToOne.class,
-            Embed_MappedToOne.class, DROP_TABLES);
+            Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class, 
+            EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class, 
+            DROP_TABLES);
     }
     
     public void testEntityA_Coll_String() {
@@ -160,6 +162,11 @@
         findObjMapKeyClass();
     }
 
+    public void testEntityA_Embed_MappedToOneCascadeDelete() {
+        createEntityA_Embed_MappedToOneCascadeDelete();
+        updateEntityA_Embed_MappedToOneCascadeDelete();
+    }
+    
     /*
      * Create EntityA_Coll_String
      */
@@ -258,6 +265,80 @@
     }
 
     /*
+     * Create EntityA_Embed_MappedToOneCascadeDelete
+     */
+    public void createEntityA_Embed_MappedToOneCascadeDelete() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        createEntityA_Embed_MappedToOneCascadeDelete(em, ID);
+        tran.begin();
+        em.flush();
+        tran.commit();
+        em.close();
+    }
+
+    public void createEntityA_Embed_MappedToOneCascadeDelete(EntityManager em, 
+        int id) {
+        EntityA_Embed_MappedToOneCascadeDelete a = 
+            new EntityA_Embed_MappedToOneCascadeDelete();
+        a.setId(id);
+        a.setName("a" + id);
+        a.setAge(id);
+        Embed_MappedToOneCascadeDelete embed = 
+            createEmbed_MappedToOneDeleteCascade(em, id, a);
+        a.setEmbed(embed);
+        em.persist(a);
+    }
+
+    public Embed_MappedToOneCascadeDelete createEmbed_MappedToOneDeleteCascade(
+        EntityManager em, int id, EntityA_Embed_MappedToOneCascadeDelete a) {
+        Embed_MappedToOneCascadeDelete embed = new Embed_MappedToOneCascadeDelete();
+        embed.setName1("name1");
+        embed.setName2("name2");
+        embed.setName3("name3");
+        EntityB2 b = new EntityB2();
+        b.setId(id);
+        b.setName("bm" + id);
+        b.setEntityA(a);
+        embed.setMappedEntityB(b);
+        em.persist(b);
+        return embed;
+    }
+    
+    /*
+     * Update EntityA_Embed_MappedToOneCascadeDelete
+     */
+    public void updateEntityA_Embed_MappedToOneCascadeDelete() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        updateEntityA_Embed_MappedToOneCascadeDelete(em, ID);
+        tran.begin();
+        em.flush();
+        tran.commit();
+        em.clear();
+        
+        EntityA_Embed_MappedToOneCascadeDelete a = 
+            em.find(EntityA_Embed_MappedToOneCascadeDelete.class, ID);
+        assertNotNull(a);
+        
+        EntityB2 b2 = em.find(EntityB2.class, ID);
+        assertNotNull(b2);
+        
+        em.close();
+    }
+
+    public void updateEntityA_Embed_MappedToOneCascadeDelete(EntityManager em, 
+        int id) {
+        EntityA_Embed_MappedToOneCascadeDelete a = 
+            em.find(EntityA_Embed_MappedToOneCascadeDelete.class, id);
+        a.setName("newa" + id);
+        a.setAge(id + 1);
+        Embed_MappedToOneCascadeDelete embed = 
+            createEmbed_MappedToOneDeleteCascade(em, id+1, a);
+        a.setEmbed(embed);
+    }
+    
+    /*
      * Create EntityA_Coll_Embed_ToOne
      */
     public void createEntityA_Coll_Embed_ToOne() {