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/01/21 07:50:17 UTC
svn commit: r736245 - in
/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats:
HandlerRelationMapTableFieldStrategy.java MapTableFieldStrategy.java
RelationRelationMapTableFieldStrategy.java
Author: faywang
Date: Tue Jan 20 22:50:16 2009
New Revision: 736245
URL: http://svn.apache.org/viewvc?rev=736245&view=rev
Log:
OPENJPA-851: ManyToMany Map support
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/RelationRelationMapTableFieldStrategy.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=736245&r1=736244&r2=736245&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 Tue Jan 20 22:50:16 2009
@@ -25,6 +25,7 @@
import org.apache.openjpa.meta.*;
import org.apache.openjpa.kernel.*;
import org.apache.openjpa.util.*;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.schema.*;
@@ -88,9 +89,7 @@
sel.whereForeignKey(field.getJoinForeignKey(),
sm.getObjectId(), field.getDefiningMapping(), store);
FieldMapping mapped = field.getMappedByMapping();
- Joins joins = null;
- if (mapped == null)
- joins = joinValueRelation(sel.newJoins(), vals[idx]);
+ Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
sel.select(vals[idx], field.getElementMapping().
getSelectSubclasses(), store, fetch, eagerMode, joins);
@@ -123,7 +122,10 @@
public Joins joinValueRelation(Joins joins, ClassMapping val) {
ValueMapping vm = field.getElementMapping();
- return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
+ ForeignKey fk = vm.getForeignKey(val);
+ if (fk == null)
+ return null;
+ return joins.joinRelation(field.getName(), fk, val,
vm.getSelectSubclasses(), false, false);
}
@@ -195,9 +197,25 @@
valsm = RelationStrategies.getStateManager(entry.getValue(),
ctx);
val.setForeignKey(row, valsm);
- rm.flushSecondaryRow(row);
+
+ // So far we poplulated the key/value of each
+ // map element owned by the entity.
+ // In the case of ToMany, and both sides
+ // use Map to represent the relation,
+ // we need to populate the key value of the owner
+ // from the view point of the owned side
+ PersistenceCapable obj = sm.getPersistenceCapable();
+ if (!populateKey(row, valsm, obj, ctx, rm, store))
+ rm.flushSecondaryRow(row);
}
}
+
+ public void setKey(Object keyObj, JDBCStore store, Row row)
+ throws SQLException {
+ ValueMapping key = field.getKeyMapping();
+ HandlerStrategies.set(key, keyObj, store, row, _kcols,
+ _kio, true);
+ }
public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException {
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=736245&r1=736244&r2=736245&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 Tue Jan 20 22:50:16 2009
@@ -19,21 +19,26 @@
package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
+import java.util.Collection;
import java.util.Map;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.FieldStrategy;
+import org.apache.openjpa.jdbc.meta.Strategy;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowImpl;
import org.apache.openjpa.jdbc.sql.RowManager;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.JavaTypes;
@@ -213,8 +218,8 @@
log.info(_loc.get("coll-owner", field, mapped));
ValueMapping elem = mapped.getElementMapping();
ForeignKey fk = elem.getForeignKey();
- field.setForeignKey(fk);
field.setJoinForeignKey(fk);
+ field.getElementMapping().setForeignKey(mapped.getJoinForeignKey());
} else
throw new MetaDataException(_loc.get("not-inv-relation",
field, mapped));
@@ -249,4 +254,51 @@
return false;
return true;
}
+
+ protected boolean populateKey(Row row, OpenJPAStateManager valsm, Object obj,
+ StoreContext ctx, RowManager rm, JDBCStore store) throws SQLException {
+ ClassMapping meta = (ClassMapping)valsm.getMetaData();
+ FieldMapping fm = getFieldMapping(meta);
+ if (fm == null)
+ return false;
+ Map mapObj = (Map)valsm.fetchObject(fm.getIndex());
+ Collection<Map.Entry> entrySets = mapObj.entrySet();
+ boolean found = false;
+ for (Map.Entry entry : entrySets) {
+ if (entry.getValue() == obj) {
+ Row newRow = (Row) ((RowImpl)row).clone();
+ Object keyObj = entry.getKey();
+ Strategy strat = fm.getStrategy();
+ if (strat instanceof HandlerRelationMapTableFieldStrategy) {
+ HandlerRelationMapTableFieldStrategy hrStrat =
+ (HandlerRelationMapTableFieldStrategy) strat;
+ hrStrat.setKey(keyObj, store, newRow);
+ } else if (keyObj instanceof PersistenceCapable) {
+ OpenJPAStateManager keysm =
+ RelationStrategies.getStateManager(entry.getKey(), ctx);
+ ValueMapping key = fm.getKeyMapping();
+ if (keysm != null)
+ key.setForeignKey(newRow, keysm);
+ else
+ key.setForeignKey(newRow, null);
+ }
+ rm.flushSecondaryRow(newRow);
+ found = true;
+ }
+ }
+ if (found)
+ return true;
+ return false;
+ }
+
+ private FieldMapping getFieldMapping(ClassMapping meta) {
+ FieldMapping[] fields = meta.getFieldMappings();
+ for (int i = 0; i < fields.length; i++) {
+ ValueMapping val = fields[i].getValueMapping();
+ if (fields[i].getMappedByMetaData() == field &&
+ val.getDeclaredTypeCode() == JavaTypes.MAP)
+ return fields[i];
+ }
+ return null;
+ }
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java?rev=736245&r1=736244&r2=736245&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java Tue Jan 20 22:50:16 2009
@@ -25,6 +25,7 @@
import org.apache.openjpa.meta.*;
import org.apache.openjpa.kernel.*;
import org.apache.openjpa.util.*;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.schema.*;
@@ -111,9 +112,7 @@
// order before select in case we're faking union with
// multiple selects; order vals used to merge results
FieldMapping mapped = field.getMappedByMapping();
- Joins joins = null;
- if (mapped == null)
- joins = joinValueRelation(sel.newJoins(), vals[idx]);
+ Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
sel.orderBy(field.getKeyMapping().getColumns(), true, true);
sel.select(vals[idx], field.getElementMapping().
getSelectSubclasses(), store, fetch, eagerMode, joins);
@@ -166,7 +165,10 @@
public Joins joinValueRelation(Joins joins, ClassMapping val) {
ValueMapping vm = field.getElementMapping();
- return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
+ ForeignKey fk = vm.getForeignKey(val);
+ if (fk == null)
+ return null;
+ return joins.joinRelation(field.getName(), fk, val,
vm.getSelectSubclasses(), false, false);
}
@@ -180,13 +182,17 @@
if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
throw new MetaDataException(_loc.get("not-relation", val));
FieldMapping mapped = field.getMappedByMapping();
- if (mapped != null)
+ DBDictionary dict = field.getMappingRepository().getDBDictionary();
+ String keyName = null;
+ if (mapped != null) {
handleMappedBy(adapt);
- else {
+ keyName = dict.getValidColumnName("vkey", field.getTable());
+ } else {
field.mapJoin(adapt, true);
mapTypeJoin(val, "value", adapt);
+ keyName = dict.getValidColumnName("key", field.getTable());
}
- mapTypeJoin(key, "key", adapt);
+ mapTypeJoin(key, keyName, adapt);
field.mapPrimaryKey(adapt);
}
@@ -211,10 +217,11 @@
public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException {
- insert(sm, rm, (Map) sm.fetchObject(field.getIndex()));
+ insert(sm, rm, (Map) sm.fetchObject(field.getIndex()), store);
}
- private void insert(OpenJPAStateManager sm, RowManager rm, Map map)
+ private void insert(OpenJPAStateManager sm, RowManager rm, Map map,
+ JDBCStore store)
throws SQLException {
if (map == null || map.isEmpty())
return;
@@ -237,7 +244,16 @@
valsm = RelationStrategies.getStateManager(entry.getValue(), ctx);
key.setForeignKey(row, keysm);
val.setForeignKey(row, valsm);
- rm.flushSecondaryRow(row);
+
+ // so far, we poplulated the key/value of each
+ // map element owned by the entity.
+ // In the case of ToMany, and both sides
+ // use Map to represent the relation,
+ // we need to populate the key value of the owner
+ // from the view point of the owned side
+ PersistenceCapable obj = sm.getPersistenceCapable();
+ if (!populateKey(row, valsm, obj, ctx, rm, store))
+ rm.flushSecondaryRow(row);
}
}
@@ -257,7 +273,7 @@
// if no fine-grained change tracking then just delete and reinsert
if (ct == null || !ct.isTracking()) {
delete(sm, store, rm);
- insert(sm, rm, map);
+ insert(sm, rm, map, store);
return;
}