svn commit: r684822 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/

1 Message Forum Options Options
Embed this topic
Permalink
Pinaki Poddar
svn commit: r684822 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/
Reply Threaded More
Print post
Permalink
Author: ppoddar
Date: Mon Aug 11 10:18:31 2008
New Revision: 684822

URL: http://svn.apache.org/viewvc?rev=684822&view=rev
Log:
OPENJPA-692: Detect orphaning relation and change row update to delete for join table entry.

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.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/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=684822&r1=684821&r2=684822&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Mon Aug 11 10:18:31 2008
@@ -73,6 +73,7 @@
     private int _fetchMode = Integer.MAX_VALUE;
     private Unique[] _joinTableUniques; // Unique constraints on JoinTable
     private Boolean _bidirectionalJoinTableOwner = null;
+    private Boolean _bidirectionalJoinTableNonOwner = null;
     
     /**
      * Constructor.
@@ -1075,10 +1076,10 @@
         ClassMapping relType = elem.getDeclaredTypeMapping();
         if (relType == null)
          return false;
-        FieldMetaData[] relFmds = relType.getFields();
+        FieldMapping[] relFmds = relType.getFieldMappings();
         for (int i=0; i<relFmds.length;i++) {
-            if (relFmds[i].getDeclaredTypeMetaData() == getDeclaringMapping()) {
-                FieldMapping rfm = (FieldMapping)relFmds[i];
+            FieldMapping rfm = relFmds[i];
+            if (rfm.getDeclaredTypeMetaData() == getDeclaringMapping()) {
          ForeignKey rjfk = rfm.getJoinForeignKey();
          if (rjfk == null)
             continue;
@@ -1086,9 +1087,55 @@
          && jfk.getTable().getColumns().length
          == jfk.getColumns().length + rjfk.getColumns().length) {
          _bidirectionalJoinTableOwner = true;
+         break;
          }
          }
         }
         return _bidirectionalJoinTableOwner.booleanValue();
     }
+    
+    /**
+     * Affirms if this field is the non-owning side of a bidirectional relation
+     * with a join table. Evaluated only once and the result cached for
+     * subsequent call. Hence must be called after resolution.
+     */
+    public boolean isBidirectionalJoinTableMappingNonOwner() {
+     if (_bidirectionalJoinTableNonOwner != null)
+     return _bidirectionalJoinTableNonOwner.booleanValue();
+    
+     _bidirectionalJoinTableNonOwner = false;
+        ForeignKey fk = getForeignKey();
+        if (fk == null)
+         return false;
+        ForeignKey jfk = getJoinForeignKey();
+        if (jfk == null)
+         return false;
+        FieldMapping mappedBy = getValueMappedByMapping();
+        if (mappedBy != null)
+         return false;
+        ValueMapping elem = getElementMapping();
+        if (elem == null)
+         return false;
+        ClassMapping relType = getDeclaredTypeMapping();
+        if (relType == null)
+         return false;
+        FieldMapping[] relFmds = relType.getFieldMappings();
+        for (int i=0; i<relFmds.length;i++) {
+            FieldMapping rfm = relFmds[i];
+            ValueMapping relem = rfm.getElementMapping();
+            if (relem != null && relem.getDeclaredTypeMapping() == getDeclaringMapping()) {
+         ForeignKey rjfk = rfm.getJoinForeignKey();
+         if (rjfk == null)
+            continue;
+         if (rjfk.getTable() == jfk.getTable()
+         && jfk.getTable().getColumns().length
+         == jfk.getColumns().length + rjfk.getColumns().length) {
+         _bidirectionalJoinTableNonOwner = true;
+         break;
+         }
+         }
+        }
+        return _bidirectionalJoinTableNonOwner.booleanValue();
+    }
+
 }

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=684822&r1=684821&r2=684822&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 Mon Aug 11 10:18:31 2008
@@ -230,7 +230,10 @@
             nullInverse(sm, rm);
             updateInverse(sm, rel, store, rm);
         } else {
-            Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
+         int action = (rel == null
+         && field.isBidirectionalJoinTableMappingNonOwner()) ?
+         Row.ACTION_DELETE : Row.ACTION_UPDATE;
+            Row row = field.getRow(sm, store, rm, action);
             if (row != null)
                 field.setForeignKey(row, rel);
         }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java?rev=684822&r1=684821&r2=684822&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java Mon Aug 11 10:18:31 2008
@@ -19,6 +19,7 @@
 package org.apache.openjpa.persistence.jdbc.mapping.bidi;
 
 import java.util.Arrays;
+import java.util.Set;
 
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
@@ -125,6 +126,20 @@
  assertEquals(0, count(Address.class));
  assertSQL("DELETE FROM .*J_PERSON_ADDRESSES .*");
  }
+
+ public void testBreakingRelationCausesDeleteFromJoinTable() {
+ EntityManager em = emf.createEntityManager();
+ Person person = em.find(Person.class, SSN);
+ em.getTransaction().begin();
+ Set<Address> addresses = person.getAddresses();
+ assertFalse(addresses.isEmpty());
+ Address address = addresses.iterator().next();
+ addresses.remove(address);
+ address.setPerson(null);
+ em.getTransaction().commit();
+
+ assertSQL("DELETE FROM .*J_PERSON_ADDRESSES .*");
+ }
 
  /**
  * Create a Person with given SSN and fixed number of addresses.