From 88f288b47a6238e3c77670fe56436ee8df94269b Mon Sep 17 00:00:00 2001 From: Fay Wang Date: Thu, 15 Jan 2009 07:05:13 +0000 Subject: [PATCH] OPENJPA-851: enhanced bi-directional map support in update operation git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@734617 13f79535-47bb-0310-9956-ffa450edef68 --- .../HandlerRelationMapTableFieldStrategy.java | 3 + .../meta/strats/RelationFieldStrategy.java | 83 +++++++++++-------- ...RelationRelationMapTableFieldStrategy.java | 3 + 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java index 5c9307bb6..e2f20bcb2 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java @@ -201,6 +201,9 @@ public class HandlerRelationMapTableFieldStrategy public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm) throws SQLException { + if (field.getMappedBy() != null) + return; + Map map = (Map) sm.fetchObject(field.getIndex()); ChangeTracker ct = null; if (map instanceof Proxy) { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java index 2c3eb143c..48bc6aac2 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java @@ -230,43 +230,49 @@ public class RelationFieldStrategy if (rel == null) return; ClassMetaData meta = rel.getMetaData(); + FieldMapping mapField = getMapField(meta); + + // there is no bi-directional map field + if (mapField == null) + return; + + Map mapObj = (Map)rel.fetchObjectField(mapField.getIndex()); + Object keyObj = getMapKeyObj(mapObj, sm.getPersistenceCapable()); + ValueMapping key = mapField.getKeyMapping(); + if (!key.isEmbedded()) { + if (keyObj instanceof PersistenceCapable) { + OpenJPAStateManager keySm = RelationStrategies. + getStateManager(keyObj, store.getContext()); + // key is an entity + ForeignKey fk = mapField.getKeyMapping(). + getForeignKey(); + ColumnIO io = new ColumnIO(); + row.setForeignKey(fk, io, keySm); + } + } else { + // key is an embeddable or basic type + FieldStrategy strategy = mapField.getStrategy(); + if (strategy instanceof + HandlerRelationMapTableFieldStrategy) { + HandlerRelationMapTableFieldStrategy strat = + (HandlerRelationMapTableFieldStrategy) strategy; + Column[] kcols = strat.getKeyColumns((ClassMapping)meta); + ColumnIO kio = strat.getKeyColumnIO(); + HandlerStrategies.set(key, keyObj, store, row, kcols, + kio, true); + } + } + } + + private FieldMapping getMapField(ClassMetaData meta) { FieldMapping[] fields = ((ClassMapping)meta).getFieldMappings(); for (int i = 0; i < fields.length; i++) { FieldMetaData mappedBy = fields[i].getMappedByMetaData(); - if (mappedBy == field) { - if (fields[i].getDeclaredTypeCode() == JavaTypes.MAP) { - Map mapObj = (Map)rel.fetchObjectField( - fields[i].getIndex()); - Object keyObj = getMapKeyObj(mapObj, - sm.getPersistenceCapable()); - ValueMapping key = fields[i].getKeyMapping(); - if (!key.isEmbedded()) { - if (keyObj instanceof PersistenceCapable) { - OpenJPAStateManager keySm = RelationStrategies. - getStateManager(keyObj, store.getContext()); - // key is an entity - ForeignKey fk = fields[i].getKeyMapping(). - getForeignKey(); - ColumnIO io = new ColumnIO(); - row.setForeignKey(fk, io, keySm); - } - } else { - // key is an embeddable or basic type - FieldStrategy strategy = fields[i].getStrategy(); - if (strategy instanceof - HandlerRelationMapTableFieldStrategy) { - HandlerRelationMapTableFieldStrategy strat = - (HandlerRelationMapTableFieldStrategy) strategy; - Column[] kcols = strat.getKeyColumns((ClassMapping)meta); - ColumnIO kio = strat.getKeyColumnIO(); - HandlerStrategies.set(key, keyObj, store, row, kcols, - kio, true); - } - } - break; - } - } - } + if (fields[i].getDeclaredTypeCode() == JavaTypes.MAP && + mappedBy == field) + return fields[i]; + } + return null; } private Object getMapKeyObj(Map mapObj, Object value) { @@ -294,8 +300,12 @@ public class RelationFieldStrategy && field.isBidirectionalJoinTableMappingNonOwner()) ? Row.ACTION_DELETE : Row.ACTION_UPDATE; Row row = field.getRow(sm, store, rm, action); - if (row != null) + if (row != null) { 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); + } } } @@ -325,6 +335,9 @@ public class RelationFieldStrategy fk.getDeleteAction() == ForeignKey.ACTION_CASCADE) { Row row = field.getRow(sm, store, rm, Row.ACTION_DELETE); row.setForeignKey(fk, null, 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); } } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java index c4c96fe0d..b7e086b81 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java @@ -243,6 +243,9 @@ public class RelationRelationMapTableFieldStrategy public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm) throws SQLException { + if (field.getMappedBy() != null) + return; + Map map = (Map) sm.fetchObject(field.getIndex()); ChangeTracker ct = null; if (map instanceof Proxy) {