OPENJPA-851: fix a bug in the embeddable processing.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@737164 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-01-23 19:48:10 +00:00
parent f1d2bf4bef
commit 209f903388
1 changed files with 32 additions and 11 deletions

View File

@ -23,10 +23,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.StateManager;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Embeddable; import org.apache.openjpa.jdbc.meta.Embeddable;
import org.apache.openjpa.jdbc.meta.FieldMapping; import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.FieldStrategy; import org.apache.openjpa.jdbc.meta.FieldStrategy;
@ -34,7 +32,6 @@ import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO; import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.MetaDataException; import org.apache.openjpa.util.MetaDataException;
@ -109,12 +106,26 @@ public abstract class EmbedValueHandler
*/ */
protected Object toDataStoreValue(OpenJPAStateManager em, ValueMapping vm, protected Object toDataStoreValue(OpenJPAStateManager em, ValueMapping vm,
JDBCStore store, Column[] cols, Object rval, int idx) { JDBCStore store, Column[] cols, Object rval, int idx) {
toDataStoreValue1(em, vm, store, cols, rval, idx);
return rval; // This is a placeholder to hold the value generated in
// toDataStoreValue1. When this method is called from
// ElementEmbedValueHandler or ObjectIdValueHandler,
// if the dimension of cols > 1, rval is an array of the
// same dimension. If the dimension of cols is 1, rval is null.
// If rval is not null, it is an array of objects and this array
// will be populated in toDatastoreValue1. If rval is null,
// a new value will be added to rvals in toDataStoreValue1
// and return to the caller.
List rvals = new ArrayList();
if (rval != null)
rvals.add(rval);
toDataStoreValue1(em, vm, store, cols, rvals, idx);
return rvals.get(0);
} }
protected int toDataStoreValue1(OpenJPAStateManager em, ValueMapping vm, protected int toDataStoreValue1(OpenJPAStateManager em, ValueMapping vm,
JDBCStore store, Column[] cols, Object rval, int idx) { JDBCStore store, Column[] cols, List rvals, int idx) {
// set rest of columns from fields // set rest of columns from fields
FieldMapping[] fms = vm.getEmbeddedMapping().getFieldMappings(); FieldMapping[] fms = vm.getEmbeddedMapping().getFieldMappings();
Object cval; Object cval;
@ -124,13 +135,20 @@ public abstract class EmbedValueHandler
if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT) if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
continue; continue;
// This recursive code is mainly to deal with situations
// where an entity contains a collection of embeddableA.
// The embeddableA element in the collection contains an
// embeddableB. The parameter vm to toDataStoreValue is
// embeddableA. If some field in embeddableA is of type
// embeddableB, recursive call is required to populate the
// value for embeddableB.
ValueMapping val = fms[i].getValueMapping(); ValueMapping val = fms[i].getValueMapping();
if (val.getEmbeddedMapping() != null) { if (val.getEmbeddedMapping() != null) {
cval = (em == null) ? null : em.fetch(i); cval = (em == null) ? null : em.fetch(i);
if (cval instanceof PersistenceCapable) { if (cval instanceof PersistenceCapable) {
OpenJPAStateManager embedSm = (OpenJPAStateManager) OpenJPAStateManager embedSm = (OpenJPAStateManager)
((PersistenceCapable)cval).pcGetStateManager(); ((PersistenceCapable)cval).pcGetStateManager();
idx = toDataStoreValue1(embedSm, val, store, cols, rval, idx); idx = toDataStoreValue1(embedSm, val, store, cols, rvals, idx);
} }
} }
@ -141,11 +159,14 @@ public abstract class EmbedValueHandler
cval = (em == null) ? null : em.fetch(i); cval = (em == null) ? null : em.fetch(i);
cval = embed.toEmbeddedDataStoreValue(cval, store); cval = embed.toEmbeddedDataStoreValue(cval, store);
if (cols.length == 1) if (cols.length == 1) {
rval = cval; // rvals is empty
else if (ecols.length == 1) rvals.add(cval); // save the return value
} else if (ecols.length == 1) {
Object rval = rvals.get(0);
((Object[]) rval)[idx++] = cval; ((Object[]) rval)[idx++] = cval;
else { } else {
Object rval = rvals.get(0);
System.arraycopy(cval, 0, rval, idx, ecols.length); System.arraycopy(cval, 0, rval, idx, ecols.length);
idx += ecols.length; idx += ecols.length;
} }