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 11:00:13 UTC
svn commit: r818410 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/
openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/c...
Author: faywang
Date: Thu Sep 24 09:00:12 2009
New Revision: 818410
URL: http://svn.apache.org/viewvc?rev=818410&view=rev
Log:
OPENJPA-1253: support non-default uni-directional one to many map using foreign key strategy
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1M_Map_FK.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_Map_FK.java
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-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.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=818410&r1=818409&r2=818410&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 09:00:12 2009
@@ -86,18 +86,26 @@
union.select(new Union.Selector() {
public void select(Select sel, int idx) {
sel.select(_kcols);
- sel.whereForeignKey(field.getJoinForeignKey(),
- sm.getObjectId(), field.getDefiningMapping(), store);
- FieldMapping mapped = field.getMappedByMapping();
- Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
-
- sel.select(vals[idx], field.getElementMapping().
- getSelectSubclasses(), store, fetch, eagerMode, joins);
-
- //### cheat: result joins only care about the relation path;
- //### thus we can use first mapping of union only
- if (idx == 0)
- resJoins[1] = joins;
+ if (isUni1ToMFK()) {
+ sel.whereForeignKey(field.getElementMapping().getForeignKey(),
+ sm.getObjectId(), field.getElementMapping().getDeclaredTypeMapping(), store);
+ } else {
+ sel.whereForeignKey(field.getJoinForeignKey(),
+ sm.getObjectId(), field.getDefiningMapping(), store);
+ }
+ if (!isUni1ToMFK()) {
+ Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
+ sel.select(vals[idx], field.getElementMapping().
+ getSelectSubclasses(), store, fetch, eagerMode, joins);
+
+ //### cheat: result joins only care about the relation path;
+ //### thus we can use first mapping of union only
+ if (idx == 0)
+ resJoins[1] = joins;
+ } else {
+ sel.select(vals[idx], field.getElementMapping().
+ getSelectSubclasses(), store, fetch, eagerMode, null);
+ }
}
});
Result res = union.execute(store, fetch);
@@ -138,11 +146,12 @@
ValueMapping val = field.getElementMapping();
if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
throw new MetaDataException(_loc.get("not-relation", val));
- FieldMapping mapped = field.getMappedByMapping();
- if (mapped != null) // map to the owner table
- handleMappedBy(adapt);
- else {
+ FieldMapping mapped = field.getMappedByMapping();
+ if ((isUni1ToMFK() && !isBi1ToMJT()) || mapped != null) {
+ // map to the owner table
+ handleMappedByForeignKey(adapt);
+ } else if ((!isUni1ToMFK() && isBi1ToMJT()) || mapped == null){
// map to a separate table
field.mapJoin(adapt, true);
if (val.getTypeMapping().isMapped()) {
@@ -178,13 +187,16 @@
throws SQLException {
if (map == null || map.isEmpty())
return;
+
if (field.getMappedBy() != null)
return;
- Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
- row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
- sm);
-
+ Row row = null;
+ if (!isUni1ToMFK()) {
+ row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+ row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+ sm);
+ }
ValueMapping key = field.getKeyMapping();
ValueMapping val = field.getElementMapping();
StoreContext ctx = store.getContext();
@@ -192,21 +204,30 @@
Map.Entry entry;
for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
entry = (Map.Entry) itr.next();
- HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
- _kio, true);
valsm = RelationStrategies.getStateManager(entry.getValue(),
ctx);
- val.setForeignKey(row, valsm);
+ if (isUni1ToMFK()){
+ row = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, valsm, true);
+ row.wherePrimaryKey(valsm);
+ val.setForeignKey(row, sm);
+ } else {
+ val.setForeignKey(row, valsm);
+ }
+ HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
+ _kio, true);
- // So far we poplulated the key/value of each
+ // So far we populated 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);
+ if (!populateKey(row, valsm, obj, ctx, rm, store)) {
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(row);
+ }
}
}
@@ -249,36 +270,66 @@
boolean canChange = val.getForeignKey().isLogical();
Object mkey;
if (canChange && !change.isEmpty()) {
- Row changeRow = rm.getSecondaryRow(field.getTable(),
- Row.ACTION_UPDATE);
- changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
+ Row changeRow = null;
+ if (!isUni1ToMFK()) {
+ changeRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_UPDATE);
+ changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+ }
+
for (Iterator itr = change.iterator(); itr.hasNext();) {
mkey = itr.next();
- HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
- val.setForeignKey(changeRow, valsm);
- rm.flushSecondaryRow(changeRow);
+ if (isUni1ToMFK()){
+ changeRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, valsm, true);
+ changeRow.wherePrimaryKey(valsm);
+ val.setForeignKey(changeRow, sm);
+ } else {
+ val.setForeignKey(changeRow, valsm);
+ }
+
+ HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(changeRow);
}
}
// delete the removes
Collection rem = ct.getRemoved();
if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
- Row delRow = rm.getSecondaryRow(field.getTable(),
- Row.ACTION_DELETE);
- delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
+ Row delRow = null;
+ if (!isUni1ToMFK()) {
+ delRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_DELETE);
+ delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+ }
for (Iterator itr = rem.iterator(); itr.hasNext();) {
- HandlerStrategies.where(key, itr.next(), store, delRow,
+ mkey = itr.next();
+ if (isUni1ToMFK()){
+ delRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, sm, true);
+ val.setForeignKey(delRow, null);
+ }
+
+ HandlerStrategies.where(key, mkey, store, delRow,
_kcols);
- rm.flushSecondaryRow(delRow);
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(delRow);
}
if (!canChange && !change.isEmpty()) {
for (Iterator itr = change.iterator(); itr.hasNext();) {
+ mkey = itr.next();
+ if (isUni1ToMFK()){
+ delRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, sm, true);
+ val.setForeignKey(delRow, null);
+ }
+
HandlerStrategies.where(key, itr.next(), store, delRow,
_kcols);
- rm.flushSecondaryRow(delRow);
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(delRow);
}
}
}
@@ -286,28 +337,47 @@
// insert the adds
Collection add = ct.getAdded();
if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
- Row addRow = rm.getSecondaryRow(field.getTable(),
- Row.ACTION_INSERT);
- addRow.setForeignKey(field.getJoinForeignKey(),
- field.getJoinColumnIO(), sm);
-
+ Row addRow = null;
+ if (!isUni1ToMFK()) {
+ addRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_INSERT);
+ addRow.setForeignKey(field.getJoinForeignKey(),
+ field.getJoinColumnIO(), sm);
+ }
for (Iterator itr = add.iterator(); itr.hasNext();) {
mkey = itr.next();
+ valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+ if (isUni1ToMFK()){
+ addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, valsm, true);
+ addRow.wherePrimaryKey(valsm);
+ val.setForeignKey(addRow, sm);
+ } else {
+ val.setForeignKey(addRow, valsm);
+ }
+
HandlerStrategies.set(key, mkey, store, addRow, _kcols,
_kio, true);
- valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
- val.setForeignKey(addRow, valsm);
- rm.flushSecondaryRow(addRow);
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(addRow);
}
if (!canChange && !change.isEmpty()) {
for (Iterator itr = change.iterator(); itr.hasNext();) {
mkey = itr.next();
+ valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+ if (isUni1ToMFK()){
+ addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
+ Row.ACTION_UPDATE, valsm, true);
+ addRow.wherePrimaryKey(valsm);
+ val.setForeignKey(addRow, sm);
+ } else {
+ val.setForeignKey(addRow, valsm);
+ }
+
HandlerStrategies.set(key, mkey, store, addRow, _kcols,
_kio, true);
- valsm = RelationStrategies.getStateManager(map.get(mkey),
- ctx);
- val.setForeignKey(addRow, valsm);
- rm.flushSecondaryRow(addRow);
+ if (!isUni1ToMFK())
+ rm.flushSecondaryRow(addRow);
}
}
}
@@ -353,7 +423,7 @@
public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException {
- if (field.getMappedBy() != null)
+ if (field.getMappedBy() != null || 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=818410&r1=818409&r2=818410&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 09:00:12 2009
@@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.Map;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
@@ -31,6 +32,7 @@
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.meta.ValueMappingInfo;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
@@ -42,6 +44,7 @@
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.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.MetaDataException;
@@ -63,10 +66,44 @@
private static final Localizer _loc = Localizer.forPackage
(MapTableFieldStrategy.class);
+ private Boolean _isNonDefaultMappingAllowed = null;
+ private Boolean _isBi1ToMJT = null;
+ private Boolean _isUni1ToMFK = null;
+
public FieldMapping getFieldMapping() {
return field;
}
+ private void isNonDefaultMapping() {
+ FieldMapping mapped = field.getMappedByMapping();
+ if (isNonDefaultMappingAllowed() &&
+ field.getAssociationType() == FieldMetaData.ONE_TO_MANY &&
+ field.getValueInfo().getColumns().size() > 0) {
+ if (mapped != null) {
+ _isBi1ToMJT = true;
+ _isUni1ToMFK = false;
+ } else {
+ _isBi1ToMJT = false;
+ _isUni1ToMFK = true;
+ }
+ } else {
+ _isBi1ToMJT = false;
+ _isUni1ToMFK = false;
+ }
+ }
+
+ protected boolean isBi1ToMJT() {
+ if (_isBi1ToMJT == null)
+ isNonDefaultMapping();
+ return _isBi1ToMJT;
+ }
+
+ protected boolean isUni1ToMFK() {
+ if (_isUni1ToMFK == null)
+ isNonDefaultMapping();
+ return _isUni1ToMFK;
+ }
+
public ClassMapping[] getIndependentKeyMappings(boolean traverse) {
return (traverse) ? field.getKeyMapping().getIndependentTypeMappings()
: ClassMapping.EMPTY_MAPPINGS;
@@ -108,8 +145,23 @@
throw new MetaDataException(_loc.get("not-map", field));
if (field.getKey().getValueMappedBy() != null)
throw new MetaDataException(_loc.get("mapped-by-key", field));
+
+ // Non-default mapping Uni-/OneToMany/ForeignKey allows schema components
+ if (isNonDefaultMappingAllowed() &&
+ field.getAssociationType() == FieldMetaData.ONE_TO_MANY &&
+ field.getMappedByMapping() == null)
+ return;
field.getValueInfo().assertNoSchemaComponents(field, !adapt);
}
+
+ protected boolean isNonDefaultMappingAllowed() {
+ if (_isNonDefaultMappingAllowed == null) {
+ OpenJPAConfiguration conf = field.getRepository().getConfiguration();
+ _isNonDefaultMappingAllowed = field.getRepository().
+ getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf);
+ }
+ return _isNonDefaultMappingAllowed;
+ }
public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException {
@@ -182,12 +234,11 @@
return ClassMapping.EMPTY_MAPPINGS;
}
- protected void handleMappedBy(boolean adapt){
+ protected void handleMappedByForeignKey(boolean adapt){
boolean criteria = field.getValueInfo().getUseClassCriteria();
// check for named inverse
FieldMapping mapped = field.getMappedByMapping();
if (mapped != null) {
- field.getMappingInfo().assertNoSchemaComponents(field, !adapt);
field.getValueInfo().assertNoSchemaComponents(field, !adapt);
mapped.resolve(mapped.MODE_META | mapped.MODE_MAPPING);
@@ -229,6 +280,21 @@
field.setUseClassCriteria(criteria);
return;
+ } else {
+ // Uni-/OneToMany/ForeingKey
+ ValueMapping val = field.getElementMapping();
+ val.getValueInfo().setColumns(field.getValueInfo().getColumns());
+ if (val.getTypeMapping().isMapped()) {
+ ValueMappingInfo vinfo = val.getValueInfo();
+ ForeignKey fk = vinfo.getTypeJoin(val, null, false, adapt);
+ val.setForeignKey(fk);
+ val.setColumnIO(vinfo.getColumnIO());
+ } else
+ RelationStrategies.mapRelationToUnmappedPC(val, "value", adapt);
+
+ val.mapConstraints("value", adapt);
+
+ return;
}
/*
// this is necessary to support openjpa 3 mappings, which didn't
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=818410&r1=818409&r2=818410&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 09:00:12 2009
@@ -375,14 +375,15 @@
}
if (_biOneToManyJoinTable != -1) { // also need to update the join table
- PersistenceCapable inversePC = (PersistenceCapable)sm.fetchObject(_biOneToManyJoinTable);
+ PersistenceCapable invPC = (PersistenceCapable)sm.fetchObject(_biOneToManyJoinTable);
Row secondaryRow = null;
- if (inversePC != null) {
+ if (invPC != null) {
secondaryRow = rm.getSecondaryRow(_biOneToManyJoinFK.getTable(),
Row.ACTION_INSERT);
secondaryRow.setForeignKey(_biOneToManyElemFK, null, sm);
secondaryRow.setForeignKey(_biOneToManyJoinFK, null,
- (OpenJPAStateManager)inversePC.pcGetStateManager());
+ RelationStrategies.getStateManager(invPC,
+ store.getContext()));
} else {
secondaryRow = rm.getSecondaryRow(_biOneToManyJoinFK.getTable(),
Row.ACTION_DELETE);
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=818410&r1=818409&r2=818410&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 Thu Sep 24 09:00:12 2009
@@ -185,7 +185,7 @@
DBDictionary dict = field.getMappingRepository().getDBDictionary();
String keyName = null;
if (mapped != null) {
- handleMappedBy(adapt);
+ handleMappedByForeignKey(adapt);
keyName = dict.getValidColumnName("vkey", field.getTable());
} else {
field.mapJoin(adapt, true);
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.java?rev=818410&r1=818409&r2=818410&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.java Thu Sep 24 09:00:12 2009
@@ -214,16 +214,18 @@
// otherwise jpa always uses <field>_<pkcol> for column name, even
// when only one col
if (target instanceof Column) {
- if (elem)
- name = vm.getFieldMapping().getName();
+ if (name == null) {
+ name = col.getName();
+ } else {
+ if (elem)
+ name = vm.getFieldMapping().getName();
+ if (isRemoveHungarianNotation())
+ name = removeHungarianNotation(name);
+ name = dict.combineNames(name, ((Column)target).getName());
- if (isRemoveHungarianNotation())
- name = removeHungarianNotation(name);
-
- name = dict.combineNames(name, ((Column)target).getName());
-
- // No need to check for uniqueness.
- name = dict.getValidColumnName(name, local, false);
+ // No need to check for uniqueness.
+ name = dict.getValidColumnName(name, local, false);
+ }
col.setName(name);
}
}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1M_Map_FK.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1M_Map_FK.java?rev=818410&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1M_Map_FK.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1M_Map_FK.java Thu Sep 24 09:00:12 2009
@@ -0,0 +1,57 @@
+/*
+ * 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_U1M_Map_FK {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int hashCode() {
+ return name.hashCode() + (int)id;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof EntityC_U1M_Map_FK)) return false;
+ EntityC_U1M_Map_FK c = (EntityC_U1M_Map_FK)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_U1M_Map_FK.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=818410&r1=818409&r2=818410&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 09:00:12 2009
@@ -392,7 +392,89 @@
em.clear();
}
+ public void testOneToManyMapRelation() {
+ List<Class<?>> types = new ArrayList<Class<?>>();
+ types.add(EntityC_U1M_Map_FK.class);
+ types.add(Uni_1ToM_Map_FK.class);
+ OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types);
+ EntityManager em = emf.createEntityManager();
+
+ try {
+ // trigger table creation
+ em.getTransaction().begin();
+ em.getTransaction().commit();
+ assertSQLFragnments(sql, "CREATE TABLE EntityC_U1M_Map_FK", "Uni1MFK_ID", "KEY0");
+ crudUni1MMapFK(em);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("OneToMany mapping failed with exception message: " + e.getMessage());
+ } finally {
+ em.close();
+ emf.close();
+ }
+ }
+
+ public void crudUni1MMapFK(EntityManager em) {
+ //create
+ Uni_1ToM_Map_FK u = new Uni_1ToM_Map_FK();
+ u.setName("uni1mfk");
+ Map<String, EntityC_U1M_Map_FK> cs = new HashMap<String, EntityC_U1M_Map_FK>();
+ EntityC_U1M_Map_FK c1 = new EntityC_U1M_Map_FK();
+ c1.setName("c1");
+ cs.put(c1.getName(), c1);
+ EntityC_U1M_Map_FK c2 = new EntityC_U1M_Map_FK();
+ c2.setName("c2");
+ cs.put(c2.getName(), c2);
+ u.setEntityCs(cs);
+
+ em.persist(u);
+ em.persist(c1);
+ em.persist(c2);
+ em.getTransaction().begin();
+ em.getTransaction().commit();
+
+ //update by adding a new C
+ cs = u.getEntityCs();
+ u.setName("uni1mfk_new");
+ EntityC_U1M_Map_FK c3 = new EntityC_U1M_Map_FK();
+ c3.setName("c3");
+ cs.put(c3.getName(), c3);
+ em.persist(c3);
+
+ em.getTransaction().begin();
+ em.getTransaction().commit();
+
+ // update by removing a c and then add this c to a new u
+ em.getTransaction().begin();
+ EntityC_U1M_Map_FK c4 = cs.remove("c1");
+
+ Uni_1ToM_Map_FK u2 = new Uni_1ToM_Map_FK();
+ u2.setName("uni1mfk2");
+ Map<String, EntityC_U1M_Map_FK> cs2 = new HashMap<String, EntityC_U1M_Map_FK>();
+ cs2.put(c4.getName(), c4);
+ u2.setEntityCs(cs2);
+ em.persist(u2);
+ em.getTransaction().commit();
+ em.clear();
+
+ //query
+ Query q = em.createQuery("SELECT u FROM Uni_1ToM_Map_FK u where u.name='uni1mfk_new'");
+ Uni_1ToM_Map_FK u1 = (Uni_1ToM_Map_FK)q.getSingleResult();
+ assertEquals(u, u1);
+ em.clear();
+ //find
+ long id = u1.getId();
+ Uni_1ToM_Map_FK findU = em.find(Uni_1ToM_Map_FK.class, id);
+ assertEquals(u, findU);
+
+ //remove
+ em.getTransaction().begin();
+ em.remove(findU);
+ em.getTransaction().commit();
+ }
+
+
private OpenJPAEntityManagerFactorySPI createEMF2_0(List<Class<?>> types) {
Map<Object,Object> map = new HashMap<Object,Object>();
map.put("openjpa.jdbc.JDBCListeners",
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_Map_FK.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_Map_FK.java?rev=818410&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_Map_FK.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_Map_FK.java Thu Sep 24 09:00:12 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.*;
+
+//non-default mapping
+//Sec 11.1.36, Example 3:
+// Unidirectional One-to-Many association using a foreign key mapping
+// In Customer class:
+// @OneToMany(orphanRemoval=true)
+// @JoinColumn(name="CUST_ID") // join column is in table for Order
+// public Set<Order> getOrders() {return orders;}
+
+@Entity
+public class Uni_1ToM_Map_FK {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
+ @JoinColumn(name="Uni1MFK_ID")
+ private Map<String, EntityC_U1M_Map_FK> entityCs = null;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map<String, EntityC_U1M_Map_FK> getEntityCs() {
+ return entityCs;
+ }
+
+ public void setEntityCs(Map<String, EntityC_U1M_Map_FK> entityCs) {
+ this.entityCs = entityCs;
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Uni_1ToM_Map_FK)) return false;
+ Uni_1ToM_Map_FK b = (Uni_1ToM_Map_FK)o;
+ if (!b.name.equals(name)) return false;
+ if (b.entityCs.size() != entityCs.size()) return false;
+ Collection<EntityC_U1M_Map_FK> coll = b.entityCs.values();
+ for (EntityC_U1M_Map_FK c : coll) {
+ if (!b.entityCs.get(c.getName()).equals(entityCs.get(c.getName())))
+ return false;
+ }
+ return true;
+ }
+}