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/09/24 22:26:20 UTC

svn commit: r818616 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/

Author: faywang
Date: Thu Sep 24 20:26:04 2009
New Revision: 818616

URL: http://svn.apache.org/viewvc?rev=818616&view=rev
Log:
OPENJPA-1253: support bi-directional one-to-many map using join table strategy

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_Map_JT.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1M_Map_JT.java   (with props)
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java?rev=818616&r1=818615&r2=818616&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java Thu Sep 24 20:26:04 2009
@@ -145,10 +145,12 @@
             throw new MetaDataException(_loc.get("not-relation", val));
         
         FieldMapping mapped = field.getMappedByMapping();
-        if ((isUni1ToMFK() && !isBi1ToMJT()) || mapped != null) { 
+        if ((isUni1ToMFK() && !isBi1ToMJT()) || 
+            (!isUni1ToMFK() && !isBi1ToMJT() && mapped != null)) { 
             // map to the owner table
             handleMappedByForeignKey(adapt);
-        } else if ((!isUni1ToMFK() && isBi1ToMJT()) || mapped == null){ 
+        } else if ((!isUni1ToMFK() && isBi1ToMJT()) || 
+            (!isUni1ToMFK() && !isBi1ToMJT() && mapped == null)){ 
             // map to a separate table
             field.mapJoin(adapt, true);
             if (val.getTypeMapping().isMapped()) {
@@ -185,7 +187,7 @@
         if (map == null || map.isEmpty())
             return;
         
-        if (field.getMappedBy() != null)
+        if (!isBi1ToMJT() && field.getMappedBy() != null)
             return;
 
         Row row = null;
@@ -237,7 +239,7 @@
 
     public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
         throws SQLException {
-        if (field.getMappedBy() != null)
+        if (field.getMappedBy() != null && !isBi1ToMJT())
             return;
 
         Map map = (Map) sm.fetchObject(field.getIndex());
@@ -420,7 +422,7 @@
     
     public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
         throws SQLException {
-        if (field.getMappedBy() != null || isUni1ToMFK())
+        if ((field.getMappedBy() != null && !isBi1ToMJT()) || isUni1ToMFK())
             return;
         super.delete(sm, store, rm);
     }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java?rev=818616&r1=818615&r2=818616&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java Thu Sep 24 20:26:04 2009
@@ -78,7 +78,7 @@
         FieldMapping mapped = field.getMappedByMapping();
         if (isNonDefaultMappingAllowed() && 
             field.getAssociationType() == FieldMetaData.ONE_TO_MANY &&
-            field.getValueInfo().getColumns().size() > 0) {
+            hasJoinColumnOrJoinTable()) {
             if (mapped != null) {
                 _isBi1ToMJT = true;
                 _isUni1ToMFK = false;
@@ -92,6 +92,13 @@
         }
     }
     
+    private boolean hasJoinColumnOrJoinTable() {
+        boolean hasJoinColumn = (field.getValueInfo().getColumns().size() > 0 ? true : false);
+        boolean hasJoinTable = (field.getMappingInfo().getTableName() != null ? true : false);
+        return hasJoinColumn || hasJoinTable;
+        
+    }
+    
     protected boolean isBi1ToMJT() {
         if (_isBi1ToMJT == null)
             isNonDefaultMapping();

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?rev=818616&r1=818615&r2=818616&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Thu Sep 24 20:26:04 2009
@@ -279,9 +279,8 @@
             updateInverse(sm, rel, store, rm);
         else {
             Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
-            if (row != null) {
-                if (_biOneToManyJoinTable == -1)
-                    field.setForeignKey(row, rel);
+            if (row != null && _biOneToManyJoinTable == -1) {
+                field.setForeignKey(row, rel);
                 // this is for bi-directional maps, the key and value of the 
                 // map are stored in the table of the mapped-by entity  
                 setMapKey(sm, rel, store, row);
@@ -366,9 +365,8 @@
                     field.isBidirectionalJoinTableMappingNonOwner()) ?
                     Row.ACTION_DELETE : Row.ACTION_UPDATE;
             Row row = field.getRow(sm, store, rm, action);
-            if (row != null) {
-                if (_biOneToManyJoinTable == -1)
-                    field.setForeignKey(row, rel);
+            if (row != null && _biOneToManyJoinTable == -1) {
+                field.setForeignKey(row, rel);
                 // this is for bi-directional maps, the key and value of the 
                 // map are stored in the table of the mapped-by entity  
                 setMapKey(sm, rel, store, row);

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_Map_JT.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_Map_JT.java?rev=818616&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_Map_JT.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_Map_JT.java Thu Sep 24 20:26:04 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.compat;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.*;
+
+
+
+@Entity
+public class Bi_1ToM_Map_JT {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @OneToMany(mappedBy="bi1mjt", fetch=FetchType.EAGER)
+    @JoinTable(
+        name="Bi1M_Map_JT_C",
+        joinColumns=
+          @JoinColumn(name="C_ID", referencedColumnName="ID"),
+          inverseJoinColumns=
+          @JoinColumn(name="B_ID", referencedColumnName="ID")
+    )
+    private Map<String, EntityC_B1M_Map_JT> entityCs = null;
+    
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public Map<String, EntityC_B1M_Map_JT> getEntityCs() { 
+        return entityCs; 
+    }
+
+    public void setEntityCs(Map<String, EntityC_B1M_Map_JT> entityCs) { 
+        this.entityCs = entityCs; 
+    }
+
+    public int hashCode() {
+        return name.hashCode();
+    }
+    
+    public boolean equals(Object o) {
+        if (!(o instanceof Bi_1ToM_Map_JT)) return false;
+        Bi_1ToM_Map_JT b = (Bi_1ToM_Map_JT)o;
+        if (!b.name.equals(name)) return false;
+        if (b.entityCs.size() != entityCs.size()) return false;
+        Collection<EntityC_B1M_Map_JT> coll = b.entityCs.values();
+        for (EntityC_B1M_Map_JT c : coll) {
+            if (!b.entityCs.get(c.getName()).equals(entityCs.get(c.getName())))
+                return false;
+        }
+        return true;
+    }
+}

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

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1M_Map_JT.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1M_Map_JT.java?rev=818616&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1M_Map_JT.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1M_Map_JT.java Thu Sep 24 20:26:04 2009
@@ -0,0 +1,68 @@
+/*
+ * 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.compat;
+
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class EntityC_B1M_Map_JT {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+    
+    @ManyToOne
+    Bi_1ToM_Map_JT bi1mjt;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public void setBi1mjt(Bi_1ToM_Map_JT bi1mjt) {
+        this.bi1mjt = bi1mjt;
+    }
+    
+    public Bi_1ToM_Map_JT getBi1mjt() {
+        return bi1mjt;
+    }
+    
+    public int hashCode() {
+        return name.hashCode() + (int)id;
+    }
+    
+    public boolean equals(Object o) {
+        if (!(o instanceof EntityC_B1M_Map_JT)) return false;
+        EntityC_B1M_Map_JT c = (EntityC_B1M_Map_JT)o;
+        if (!c.name.equals(name)) return false;
+        if (c.id != id) return false;
+        return true;
+    }
+}

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

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java?rev=818616&r1=818615&r2=818616&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java Thu Sep 24 20:26:04 2009
@@ -396,6 +396,8 @@
         List<Class<?>> types = new ArrayList<Class<?>>();
         types.add(EntityC_U1M_Map_FK.class);
         types.add(Uni_1ToM_Map_FK.class);
+        types.add(EntityC_B1M_Map_JT.class);
+        types.add(Bi_1ToM_Map_JT.class);
         OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types);
         EntityManager em = emf.createEntityManager();
         
@@ -405,6 +407,7 @@
             em.getTransaction().commit();
             assertSQLFragnments(sql, "CREATE TABLE EntityC_U1M_Map_FK", "Uni1MFK_ID", "KEY0");
             crudUni1MMapFK(em);
+            crudBi1MMapJT(em);
         } catch (Exception e) {
             e.printStackTrace();
             fail("OneToMany mapping failed with exception message: " + e.getMessage());
@@ -474,6 +477,54 @@
         em.getTransaction().commit();
     }
     
+    public void crudBi1MMapJT(EntityManager em) {
+        Bi_1ToM_Map_JT b = new Bi_1ToM_Map_JT();
+        b.setName("bi1mfk");
+        Map<String, EntityC_B1M_Map_JT> cs = new HashMap<String, EntityC_B1M_Map_JT>();
+        EntityC_B1M_Map_JT c = new EntityC_B1M_Map_JT();
+        c.setName("c");
+        c.setBi1mjt(b);
+        cs.put(c.getName(), c);
+        b.setEntityCs(cs);
+        em.persist(b);
+        em.persist(c);
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+
+        //update
+        em.getTransaction().begin();
+        cs = b.getEntityCs();
+        b.setName("newName");
+        EntityC_B1M_Map_JT c1 = new EntityC_B1M_Map_JT();
+        c1.setName("c1");
+        cs.put(c1.getName(), c1);
+        c1.setBi1mjt(b);
+        em.persist(c1);
+        em.getTransaction().commit();
+        em.clear();
+        
+        //query
+        Query q = em.createQuery("SELECT u FROM Bi_1ToM_Map_JT u");
+        Bi_1ToM_Map_JT b1 = (Bi_1ToM_Map_JT)q.getSingleResult();
+        assertEquals(b, b1);
+        em.clear();
+
+        // query the owner
+        q = em.createQuery("SELECT c FROM EntityC_B1M_Map_JT c");
+        List<EntityC_B1M_Map_JT> cs1 = q.getResultList();
+        System.err.println("cs1 size = " + cs1.size());
+        em.clear();
+        
+        //find
+        long id = b1.getId();
+        Bi_1ToM_Map_JT b2 = em.find(Bi_1ToM_Map_JT.class, id);
+        assertEquals(b, b2);
+        
+        //remove
+        em.getTransaction().begin();
+        em.remove(b2);
+        em.getTransaction().commit();
+    }
     
     private OpenJPAEntityManagerFactorySPI createEMF2_0(List<Class<?>> types) {
         Map<Object,Object> map = new HashMap<Object,Object>();