You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/11/04 00:15:10 UTC
svn commit: r471045 [1/2] - in /incubator/openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-jd...
Author: awhite
Date: Fri Nov 3 15:15:08 2006
New Revision: 471045
URL: http://svn.apache.org/viewvc?view=rev&rev=471045
Log:
Support many-one and one-one relations as primary key fields.
Added:
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreManyOneIdOwner.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwner.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwnerId.java
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneIdOwner.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestManyOneAsId.java
Modified:
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GetObjectId.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DelegatingJoinable.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/PrimitiveFieldStrategy.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StringFieldStrategy.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/schemas-doctype.rsrc
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/StateManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataInheritanceComparator.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ProxySetupStateManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_pc.xml
incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_pc.xml
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GetObjectId.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GetObjectId.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GetObjectId.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GetObjectId.java Fri Nov 3 15:15:08 2006
@@ -114,16 +114,16 @@
while (!mapping.isPrimaryKeyObjectId(false))
mapping = mapping.getJoinablePCSuperclassMapping();
- // relies on single-column primary key field mappings
Column[] cols = mapping.getPrimaryKeyColumns();
- Object[] ordered = new Object[cols.length];
+ Object[] vals = new Object[cols.length];
Joinable join;
for (int i = 0; i < cols.length; i++) {
join = mapping.assertJoinable(cols[i]);
- ordered[i] = pks[mapping.getField(join.getFieldIndex()).
+ vals[i] = pks[mapping.getField(join.getFieldIndex()).
getPrimaryKeyIndex()];
+ vals[i] = join.getJoinValue(vals[i], cols[i], ctx.store);
}
- return ordered;
+ return vals;
}
public void select(Select sel, ExpContext ctx, ExpState state,
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java Fri Nov 3 15:15:08 2006
@@ -180,7 +180,7 @@
if (vals[pkIdx] == null) {
res.startDataRequest(fm);
vals[pkIdx] = join.getPrimaryKeyValue(res, join.getColumns(),
- fk, joins);
+ fk, store, joins);
res.endDataRequest();
if (vals[pkIdx] == null)
return null;
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DelegatingJoinable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DelegatingJoinable.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DelegatingJoinable.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DelegatingJoinable.java Fri Nov 3 15:15:08 2006
@@ -88,10 +88,10 @@
return _join.getFieldIndex();
}
- public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
+ JDBCStore store, Joins joins)
throws SQLException {
- return _join.getPrimaryKeyValue(res, cols, fk, joins);
+ return _join.getPrimaryKeyValue(res, cols, fk, store, joins);
}
public Column[] getColumns() {
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java Fri Nov 3 15:15:08 2006
@@ -52,7 +52,7 @@
* {@link ForeignKey#getColumn}.
*/
public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ JDBCStore store, Joins joins)
throws SQLException;
/**
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Fri Nov 3 15:15:08 2006
@@ -303,8 +303,8 @@
// define superclass fields after mapping class, so we can tell whether
// the class is mapped and needs to redefine abstract superclass fields
getStrategyInstaller().installStrategy(mapping);
- mapping.defineSuperclassFields(mapping.
- getJoinablePCSuperclassMapping() == null);
+ mapping.defineSuperclassFields(mapping.getJoinablePCSuperclassMapping()
+ == null);
// resolve everything that doesn't involve relations to allow relation
// mappings to use the others as joinables
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Fri Nov 3 15:15:08 2006
@@ -949,6 +949,10 @@
throw new InternalException();
}
+ public Object getPCPrimaryKey(Object oid, int field) {
+ throw new InternalException();
+ }
+
public StateManager replaceStateManager(StateManager sm) {
throw new InternalException();
}
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java Fri Nov 3 15:15:08 2006
@@ -287,7 +287,7 @@
}
public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ JDBCStore store, Joins joins)
throws SQLException {
Column col;
Object val = null;
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java Fri Nov 3 15:15:08 2006
@@ -50,7 +50,7 @@
}
public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ JDBCStore store, Joins joins)
throws SQLException {
Column col = cols[0];
if (fk != null)
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/PrimitiveFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/PrimitiveFieldStrategy.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/PrimitiveFieldStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/PrimitiveFieldStrategy.java Fri Nov 3 15:15:08 2006
@@ -287,12 +287,13 @@
}
public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ JDBCStore store, Joins joins)
throws SQLException {
Column col = cols[0];
if (fk != null)
col = fk.getColumn(col);
- return res.getObject(col, null, joins);
+ return JavaTypes.convert(res.getObject(col, null, joins),
+ field.getTypeCode());
}
public Column[] getColumns() {
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Fri Nov 3 15:15:08 2006
@@ -24,12 +24,14 @@
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Embeddable;
import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.Joinable;
import org.apache.openjpa.jdbc.meta.MappingInfo;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
@@ -45,8 +47,12 @@
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.ApplicationIds;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.MetaDataException;
import org.apache.openjpa.util.OpenJPAId;
+import org.apache.openjpa.util.UnsupportedException;
+import serp.util.Numbers;
/**
* Mapping for a single-valued relation to another entity.
@@ -56,7 +62,7 @@
*/
public class RelationFieldStrategy
extends AbstractFieldStrategy
- implements Embeddable {
+ implements Joinable, Embeddable {
private static final Localizer _loc = Localizer.forPackage
(RelationFieldStrategy.class);
@@ -146,8 +152,19 @@
adapt);
field.setUseClassCriteria(criteria);
- field.mapConstraints(field.getName(), adapt);
field.mapPrimaryKey(adapt);
+ PrimaryKey pk = field.getTable().getPrimaryKey();
+ if (field.isPrimaryKey()) {
+ Column[] cols = field.getColumns();
+ if (pk != null && (adapt || pk.isLogical()))
+ for (int i = 0; i < cols.length; i++)
+ pk.addColumn(cols[i]);
+ for (int i = 0; i < cols.length; i++)
+ field.getDefiningMapping().setJoinable(cols[i], this);
+ }
+
+ // map constraints after pk so we don't re-index / re-unique pk col
+ field.mapConstraints(field.getName(), adapt);
}
/**
@@ -690,6 +707,96 @@
field.getSelectSubclasses(), false, false);
return joins.joinRelation(field.getName(), field.getForeignKey(clss[0]),
clss[0], field.getSelectSubclasses(), false, false);
+ }
+
+ ///////////////////////////
+ // Joinable implementation
+ ///////////////////////////
+
+ public int getFieldIndex() {
+ return field.getIndex();
+ }
+
+ public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
+ JDBCStore store, Joins joins)
+ throws SQLException {
+ ClassMapping relmapping = field.getTypeMapping();
+ if (relmapping.getIdentityType() == ClassMapping.ID_DATASTORE) {
+ Column col = cols[0];
+ if (fk != null)
+ col = fk.getColumn(col);
+ long id = res.getLong(col, joins);
+ if (field.getObjectIdFieldTypeCode() == JavaTypes.LONG)
+ return Numbers.valueOf(id);
+ return store.newDataStoreId(id, relmapping, field.getPolymorphic()
+ != ValueMapping.POLY_FALSE);
+ }
+
+ if (relmapping.isOpenJPAIdentity())
+ return ((Joinable) relmapping.getPrimaryKeyFieldMappings()[0].
+ getStrategy()).getPrimaryKeyValue(res, cols, fk, store, joins);
+
+ if (cols == getColumns() && fk == null)
+ fk = field.getForeignKey();
+ else
+ fk = createTranslatingForeignKey(relmapping, cols, fk);
+ return relmapping.getObjectId(store, res, fk,
+ field.getPolymorphic() != ValueMapping.POLY_FALSE, joins);
+ }
+
+ /**
+ * Create a faux foreign key that translates between the columns to pull
+ * the data from and our related type's primary key columns.
+ */
+ private ForeignKey createTranslatingForeignKey(ClassMapping relmapping,
+ Column[] gcols, ForeignKey gfk) {
+ ForeignKey fk = field.getForeignKey();
+ Column[] cols = fk.getColumns();
+
+ ForeignKey tfk = null;
+ Column tcol;
+ for (int i = 0; i < gcols.length; i++) {
+ tcol = gcols[i];
+ if (gfk != null)
+ tcol = gfk.getColumn(tcol);
+ if (tfk == null)
+ tfk = new ForeignKey(null, tcol.getTable());
+ tfk.join(tcol, fk.getPrimaryKeyColumn(cols[i]));
+ }
+ return tfk;
+ }
+
+ public Object getJoinValue(Object fieldVal, Column col, JDBCStore store) {
+ Object o = field.getForeignKey().getConstant(col);
+ if (o != null)
+ return o;
+ col = field.getForeignKey().getPrimaryKeyColumn(col);
+ if (col == null)
+ throw new InternalException();
+
+ ClassMapping relmapping = field.getTypeMapping();
+ Joinable j = field.getTypeMapping().assertJoinable(col);
+ if (ImplHelper.isManageable(fieldVal))
+ fieldVal = store.getContext().getObjectId(fieldVal);
+ if (fieldVal instanceof OpenJPAId)
+ fieldVal = ((OpenJPAId) fieldVal).getIdObject();
+ else if (relmapping.getObjectIdType() != null
+ && relmapping.getObjectIdType().isInstance(fieldVal)) {
+ Object[] pks = ApplicationIds.toPKValues(fieldVal, relmapping);
+ fieldVal = pks[relmapping.getField(j.getFieldIndex()).
+ getPrimaryKeyIndex()];
+ }
+ return j.getJoinValue(fieldVal, col, store);
+ }
+
+ public Object getJoinValue(OpenJPAStateManager sm, Column col,
+ JDBCStore store) {
+ return getJoinValue(sm.fetch(field.getIndex()), col, store);
+ }
+
+ public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store,
+ Column col, Object autoInc) {
+ throw new UnsupportedException();
}
/////////////////////////////
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StringFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StringFieldStrategy.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StringFieldStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StringFieldStrategy.java Fri Nov 3 15:15:08 2006
@@ -201,7 +201,7 @@
}
public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
- Joins joins)
+ JDBCStore store, Joins joins)
throws SQLException {
Column col = cols[0];
if (fk != null)
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/schemas-doctype.rsrc
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/schemas-doctype.rsrc?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/schemas-doctype.rsrc (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/schemas-doctype.rsrc Fri Nov 3 15:15:08 2006
@@ -2,7 +2,7 @@
<!ELEMENT schemas (schema)*>
<!ELEMENT schema (table|sequence)*>
<!ATTLIST schema name CDATA #IMPLIED>
- <!ELEMENT table (column|index|pk|fk)+>
+ <!ELEMENT table (column|index|pk|fk|unique)+>
<!ATTLIST table name CDATA #REQUIRED>
<!ELEMENT column EMPTY>
<!ATTLIST column name CDATA #REQUIRED>
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java Fri Nov 3 15:15:08 2006
@@ -312,7 +312,6 @@
// collect info on id type
String className = getClassName();
-
String packageName = Strings.getPackageName(oidClass);
String packageDec = "";
if (packageName.length() > 0)
@@ -502,13 +501,12 @@
pkgs.add("java.io");
pkgs.add("java.util");
+ Class type;
for (int i = 0; i < _fields.length; i++) {
- if (_fields[i].getDeclaredType() != byte[].class
- && _fields[i].getDeclaredType() != char[].class
- && !_fields[i].getDeclaredType().getName().
- startsWith("java.sql.")) {
- pkgs.add(Strings.getPackageName
- (_fields[i].getDeclaredType()));
+ type = _fields[i].getObjectIdFieldType();
+ if (type != byte[].class && type != char[].class
+ && !type.getName().startsWith("java.sql.")) {
+ pkgs.add(Strings.getPackageName(type));
}
}
return pkgs;
@@ -532,13 +530,14 @@
* Return the type name to declare the given field as.
*/
private String getTypeName(FieldMetaData fmd) {
- if (fmd.getDeclaredType() == byte[].class)
+ Class type = fmd.getObjectIdFieldType();
+ if (type == byte[].class)
return "byte[]";
- if (fmd.getDeclaredType() == char[].class)
+ if (type == char[].class)
return "char[]";
- if (fmd.getDeclaredType().getName().startsWith("java.sql."))
- return fmd.getDeclaredType().getName();
- return Strings.getClassName(fmd.getDeclaredType());
+ if (type.getName().startsWith("java.sql."))
+ return type.getName();
+ return Strings.getClassName(type);
}
/**
@@ -626,6 +625,16 @@
code.openParen(true).append("String str").closeParen();
code.openBrace(2).endl();
+ // if we have any Object-type fields, die immediately
+ for (int i = 0; i < _fields.length; i++) {
+ if (_fields[i].getObjectIdFieldType() != Object.class)
+ continue;
+ code.tab(2).append("throw new UnsupportedOperationException").
+ parens().append(";").endl();
+ code.closeBrace(2);
+ return code.toString();
+ }
+
if (toke != null) {
code.tab(2).append(toke).append(" toke = ");
if (hasSuperclass) {
@@ -677,7 +686,7 @@
parse.append("this.");
parse.append(field.getName()).append(" = ");
- Class type = field.getDeclaredType();
+ Class type = field.getObjectIdFieldType();
if (type == Date.class) {
parse.append("new Date").openParen(true).
append("Long.parseLong").openParen(true).
@@ -788,6 +797,7 @@
}
String name;
+ Class type;
for (int i = 0; i < _fields.length; i++) {
if (i == 0) {
code.endl().tab(2).append(className).append(" other = ").
@@ -802,14 +812,15 @@
code.endl().tab(3).append("&& ");
name = _fields[i].getName();
- if (_fields[i].getDeclaredType().isPrimitive()) {
+ type = _fields[i].getObjectIdFieldType();
+ if (type.isPrimitive()) {
code.openParen(false).append(name).append(" == ").
append("other.").append(name).closeParen();
- } else if (_fields[i].getDeclaredType() == byte[].class) {
+ } else if (type == byte[].class) {
code.openParen(false).append("equals").openParen(true).
append(name).append(", ").append("other.").
append(name).closeParen().closeParen();
- } else if (_fields[i].getDeclaredType() == char[].class) {
+ } else if (type == char[].class) {
// ((name == null && other.name == null)
// || (name != null && String.valueOf (name).
// equals (String.valueOf (other.name))))
@@ -908,18 +919,19 @@
String name = field.getName();
if ("rs".equals(name))
name = "this." + name;
- if (field.getDeclaredType().isPrimitive()) {
- if (field.getDeclaredType() == boolean.class) {
+ Class type = field.getObjectIdFieldType();
+ if (type.isPrimitive()) {
+ if (type == boolean.class) {
// ((name) ? 1 : 0)
code.append("(").openParen(false).append(name).closeParen().
append(" ? 1 : 0").append(")");
- } else if (field.getDeclaredType() == long.class) {
+ } else if (type == long.class) {
// (int) (name ^ (name >>> 32))
code.openParen(false).append("int").closeParen().
append(" ").openParen(false).append(name).
append(" ^ ").openParen(false).append(name).
append(" >>> 32").closeParen().closeParen();
- } else if (field.getDeclaredType() == double.class) {
+ } else if (type == double.class) {
// (int) (Double.doubleToLongBits (name)
// ^ (Double.doubleToLongBits (name) >>> 32))
code.openParen(false).append("int").closeParen().
@@ -930,22 +942,22 @@
append("Double.doubleToLongBits").openParen(true).
append(name).closeParen().append(" >>> 32").
closeParen().closeParen();
- } else if (field.getDeclaredType() == float.class) {
+ } else if (type == float.class) {
// Float.floatToIntBits (name)
code.append("Float.floatToIntBits").openParen(true).
append(name).closeParen();
- } else if (field.getDeclaredType() == int.class)
+ } else if (type == int.class)
code.append(name);
else {
// (int) name
code.openParen(false).append("int").closeParen().
append(" ").append(name);
}
- } else if (field.getDeclaredType() == byte[].class) {
+ } else if (type == byte[].class) {
// hashCode (name);
code.append("hashCode").openParen(true).append(name).
closeParen();
- } else if (field.getDeclaredType() == char[].class) {
+ } else if (type == char[].class) {
// ((name == null) ? 0 : String.valueOf (name).hashCode ())
code.append("(").openParen(false).append(name).
append(" == null").closeParen().append(" ? 0 : ").
@@ -974,6 +986,7 @@
openBrace(2).endl();
String name;
+ Class type;
String appendDelimiter = "+ \"" + _token + "\" + ";
for (int i = 0; i < _fields.length; i++) {
// if this is not the first field, add a +
@@ -990,17 +1003,18 @@
code.endl().tab(3).append(appendDelimiter);
name = _fields[i].getName();
- if (_fields[i].getDeclaredType() == String.class)
+ type = _fields[i].getObjectIdFieldType();
+ if (type == String.class)
code.append(name);
- else if (_fields[i].getDeclaredType() == byte[].class)
+ else if (type == byte[].class)
code.append("toString").openParen(true).
append(name).closeParen();
- else if (_fields[i].getDeclaredType() == char[].class)
+ else if (type == char[].class)
code.openParen(true).openParen(true).append(name).
append(" == null").closeParen().append(" ? \"null\"").
append(": String.valueOf").openParen(true).
append(name).closeParen().closeParen();
- else if (_fields[i].getDeclaredType() == Date.class)
+ else if (type == Date.class)
code.openParen(true).openParen(true).append(name).
append(" == null").closeParen().append(" ? \"null\"").
endl().tab(4).append(": String.valueOf").
@@ -1448,7 +1462,8 @@
public static interface ObjectIdLoader
{
/**
- * Turn on the loading of all identity classes, even if they don't exist.
+ * Turn on the loading of all identity classes, even if they don't
+ * exist.
*/
public void setLoadObjectIds ();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java Fri Nov 3 15:15:08 2006
@@ -31,6 +31,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -59,7 +60,15 @@
import org.apache.openjpa.meta.ValueStrategies;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.ByteId;
+import org.apache.openjpa.util.CharId;
+import org.apache.openjpa.util.DateId;
+import org.apache.openjpa.util.Id;
+import org.apache.openjpa.util.IntId;
+import org.apache.openjpa.util.LongId;
import org.apache.openjpa.util.ObjectId;
+import org.apache.openjpa.util.ShortId;
+import org.apache.openjpa.util.StringId;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.UserException;
import serp.bytecode.BCClass;
@@ -131,7 +140,6 @@
private final ClassMetaData _meta;
private final Log _log;
private Collection _oids = null;
-
private boolean _defCons = true;
private boolean _fail = false;
private File _dir = null;
@@ -1285,14 +1293,14 @@
code.constant().setNull(); // return null;
else {
// return <versionField>;
- Class wrapper = unwrapVersionField(versionField);
- if (wrapper != null) {
+ Class wrapper = toPrimitiveWrapper(versionField);
+ if (wrapper != versionField.getDeclaredType()) {
code.anew().setType(wrapper);
code.dup();
}
loadManagedInstance(code, false);
addGetManagedValueCode(code, versionField);
- if (wrapper != null)
+ if (wrapper != versionField.getDeclaredType())
code.invokespecial().setMethod(wrapper, "<init>", void.class,
new Class[]{ versionField.getDeclaredType() });
}
@@ -1313,20 +1321,26 @@
* Return the version field type as a primitive wrapper, or null if
* the version field is not primitive.
*/
- private Class unwrapVersionField(FieldMetaData fmd) {
+ private Class toPrimitiveWrapper(FieldMetaData fmd) {
switch (fmd.getDeclaredTypeCode()) {
+ case JavaTypes.BOOLEAN:
+ return Boolean.class;
case JavaTypes.BYTE:
return Byte.class;
case JavaTypes.CHAR:
return Character.class;
+ case JavaTypes.DOUBLE:
+ return Double.class;
+ case JavaTypes.FLOAT:
+ return Float.class;
case JavaTypes.INT:
return Integer.class;
- case JavaTypes.SHORT:
- return Short.class;
case JavaTypes.LONG:
return Long.class;
+ case JavaTypes.SHORT:
+ return Short.class;
}
- return null;
+ return fmd.getDeclaredType();
}
/**
@@ -1495,7 +1509,7 @@
else
code.aload().setParam(0);
- if (!_meta.isOpenJPAIdentity() && _meta.isObjectIdTypeShared()) {
+ if (_meta.isObjectIdTypeShared()) {
// oid = ((ObjectId) id).getId ();
code.checkcast().setType(ObjectId.class);
code.invokevirtual().setMethod(ObjectId.class, "getId",
@@ -1509,9 +1523,12 @@
code.astore().setLocal(id);
// int inherited = pcInheritedFieldCount;
- code.getstatic().setField(INHERIT, int.class);
- int inherited = code.getNextLocalsIndex();
- code.istore().setLocal(inherited);
+ int inherited = 0;
+ if (fieldManager) {
+ code.getstatic().setField(INHERIT, int.class);
+ inherited = code.getNextLocalsIndex();
+ code.istore().setLocal(inherited);
+ }
// id.<field> = fs.fetch<type>Field (<index>); or...
// id.<field> = pc.<field>;
@@ -1522,8 +1539,9 @@
if (!fmds[i].isPrimaryKey())
continue;
- type = fmds[i].getDeclaredType();
name = fmds[i].getName();
+ type = fmds[i].getObjectIdFieldType();
+
code.aload().setLocal(id);
if (fieldManager) {
code.aload().setParam(0);
@@ -1542,11 +1560,14 @@
} else {
loadManagedInstance(code, false);
addGetManagedValueCode(code, fmds[i]);
+
+ // get id/pk from pc instance
+ if (fmds[i].getDeclaredTypeCode() == JavaTypes.PC)
+ addExtractObjectIdFieldValueCode(code, fmds[i]);
}
if (_meta.getAccessType() == ClassMetaData.ACCESS_FIELD)
- code.putfield().setField(findDeclaredField(oidType,
- name));
+ code.putfield().setField(findDeclaredField(oidType, name));
else
code.invokevirtual().setMethod(findDeclaredMethod
(oidType, "set" + StringUtils.capitalize(name),
@@ -1559,6 +1580,168 @@
}
/**
+ * Add code to extract the id of the given primary key relation field for
+ * setting into an objectid instance.
+ */
+ private void addExtractObjectIdFieldValueCode(Code code, FieldMetaData pk) {
+ // if (val != null)
+ // val = ((PersistenceCapable) val).pcFetchObjectId();
+ int pc = code.getNextLocalsIndex();
+ code.astore().setLocal(pc);
+ code.aload().setLocal(pc);
+ JumpInstruction ifnull1 = code.ifnull();
+ code.aload().setLocal(pc);
+ code.checkcast().setType(PersistenceCapable.class);
+ code.invokeinterface().setMethod(PersistenceCapable.class,
+ PRE + "FetchObjectId", Object.class, null);
+ int oid = code.getNextLocalsIndex();
+ code.astore().setLocal(oid);
+ code.aload().setLocal(oid);
+ JumpInstruction ifnull2 = code.ifnull();
+
+ // for datastore / single-field identity:
+ // if (val != null)
+ // val = ((OpenJPAId) val).getId();
+ ClassMetaData pkmeta = pk.getDeclaredTypeMetaData();
+ int pkcode = pk.getObjectIdFieldTypeCode();
+ Class pktype = pk.getObjectIdFieldType();
+ if (pkmeta.getIdentityType() == ClassMetaData.ID_DATASTORE
+ && pkcode == JavaTypes.LONG) {
+ code.aload().setLocal(oid);
+ code.checkcast().setType(Id.class);
+ code.invokevirtual().setMethod(Id.class, "getId",
+ long.class, null);
+ } else if (pkmeta.getIdentityType() == ClassMetaData.ID_DATASTORE) {
+ code.aload().setLocal(oid);
+ } else if (pkmeta.isOpenJPAIdentity()) {
+ switch (pkcode) {
+ case JavaTypes.BYTE_OBJ:
+ code.anew().setType(Byte.class);
+ code.dup();
+ // no break
+ case JavaTypes.BYTE:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(ByteId.class);
+ code.invokevirtual().setMethod(ByteId.class, "getId",
+ byte.class, null);
+ if (pkcode == JavaTypes.BYTE_OBJ)
+ code.invokespecial().setMethod(Byte.class, "<init>",
+ void.class, new Class[] {byte.class});
+ break;
+ case JavaTypes.CHAR_OBJ:
+ code.anew().setType(Character.class);
+ code.dup();
+ // no break
+ case JavaTypes.CHAR:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(CharId.class);
+ code.invokevirtual().setMethod(CharId.class, "getId",
+ char.class, null);
+ if (pkcode == JavaTypes.CHAR_OBJ)
+ code.invokespecial().setMethod(Character.class,
+ "<init>", void.class, new Class[] {char.class});
+ break;
+ case JavaTypes.INT_OBJ:
+ code.anew().setType(Integer.class);
+ code.dup();
+ // no break
+ case JavaTypes.INT:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(IntId.class);
+ code.invokevirtual().setMethod(IntId.class, "getId",
+ int.class, null);
+ if (pkcode == JavaTypes.INT_OBJ)
+ code.invokespecial().setMethod(Integer.class, "<init>",
+ void.class, new Class[] {int.class});
+ break;
+ case JavaTypes.LONG_OBJ:
+ code.anew().setType(Long.class);
+ code.dup();
+ // no break
+ case JavaTypes.LONG:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(LongId.class);
+ code.invokevirtual().setMethod(LongId.class, "getId",
+ long.class, null);
+ if (pkcode == JavaTypes.LONG_OBJ)
+ code.invokespecial().setMethod(Long.class, "<init>",
+ void.class, new Class[] {long.class});
+ break;
+ case JavaTypes.SHORT_OBJ:
+ code.anew().setType(Short.class);
+ code.dup();
+ // no break
+ case JavaTypes.SHORT:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(ShortId.class);
+ code.invokevirtual().setMethod(ShortId.class, "getId",
+ short.class, null);
+ if (pkcode == JavaTypes.SHORT_OBJ)
+ code.invokespecial().setMethod(Short.class, "<init>",
+ void.class, new Class[]{short.class});
+ break;
+ case JavaTypes.DATE:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(DateId.class);
+ code.invokevirtual().setMethod(DateId.class, "getId",
+ Date.class, null);
+ break;
+ case JavaTypes.STRING:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(StringId.class);
+ code.invokevirtual().setMethod(StringId.class, "getId",
+ String.class, null);
+ break;
+ default:
+ code.aload().setLocal(oid);
+ code.checkcast().setType(ObjectId.class);
+ code.invokevirtual().setMethod(ObjectId.class, "getId",
+ Object.class, null);
+ }
+ } else if (pkmeta.getObjectIdType() != null) {
+ code.aload().setLocal(oid);
+ code.checkcast().setType(pktype);
+ } else
+ code.aload().setLocal(oid);
+ JumpInstruction go2 = code.go2();
+
+ // if (val == null)
+ // val = <default>;
+ Instruction def;
+ switch (pkcode) {
+ case JavaTypes.BOOLEAN:
+ def = code.constant().setValue(false);
+ break;
+ case JavaTypes.BYTE:
+ def = code.constant().setValue((byte) 0);
+ break;
+ case JavaTypes.CHAR:
+ def = code.constant().setValue((char) 0);
+ break;
+ case JavaTypes.DOUBLE:
+ def = code.constant().setValue(0D);
+ break;
+ case JavaTypes.FLOAT:
+ def = code.constant().setValue(0F);
+ break;
+ case JavaTypes.INT:
+ def = code.constant().setValue(0);
+ break;
+ case JavaTypes.LONG:
+ def = code.constant().setValue(0L);
+ break;
+ case JavaTypes.SHORT:
+ def = code.constant().setValue((short) 0);
+ break;
+ default:
+ def = code.constant().setNull();
+ }
+ ifnull1.setTarget(def);
+ ifnull2.setTarget(def);
+ go2.setTarget(code.nop());
+ }
+
+ /**
* Adds the <code>pcCopyKeyFieldsFromObjectId</code> methods
* to classes using application identity.
*/
@@ -1566,8 +1749,8 @@
throws NoSuchMethodException {
// public void pcCopyKeyFieldsFromObjectId (ObjectIdFieldConsumer fc,
// Object oid)
- String[] args = (fieldManager) ?
- new String[]{ OIDFCTYPE.getName(), Object.class.getName() }
+ String[] args = (fieldManager)
+ ? new String[]{ OIDFCTYPE.getName(), Object.class.getName() }
: new String[]{ Object.class.getName() };
BCMethod method = _pc.declareMethod(PRE + "CopyKeyFieldsFromObjectId",
void.class.getName(), args);
@@ -1601,14 +1784,6 @@
code.checkcast().setType(oidType);
code.astore().setLocal(id);
- // int inherited = pcInheritedFieldCount;
- int inherited = 0;
- if (fieldManager) {
- code.getstatic().setField(INHERIT, int.class);
- inherited = code.getNextLocalsIndex();
- code.istore().setLocal(inherited);
- }
-
// fs.store<type>Field (<index>, id.<field>); or...
// this.<field> = id.<field>
// or for single field identity: id.getId ()
@@ -1621,41 +1796,56 @@
continue;
name = fmds[i].getName();
- type = fmds[i].getDeclaredType();
- unwrapped = unwrapSingleFieldIdentity(fmds[i]);
-
- if (fieldManager) {
- code.aload().setParam(0);
+ type = fmds[i].getObjectIdFieldType();
+ if (!fieldManager
+ && fmds[i].getDeclaredTypeCode() == JavaTypes.PC) {
+ // sm.getPCPrimaryKey(oid, i + pcInheritedFieldCount);
+ loadManagedInstance(code, false);
+ code.dup(); // leave orig on stack to set value into
+ code.getfield().setField(SM, SMTYPE);
+ code.aload().setLocal(id);
code.constant().setValue(i);
- code.iload().setLocal(inherited);
+ code.getstatic().setField(INHERIT, int.class);
code.iadd();
- } else
- loadManagedInstance(code, false);
-
- if (unwrapped != type) {
- code.anew().setType(type);
- code.dup();
- }
- code.aload().setLocal(id);
- if (_meta.isOpenJPAIdentity()) {
- if (oidType == ObjectId.class) {
- code.invokevirtual().setMethod(oidType, "getId",
- Object.class, null);
- if (!fieldManager && fmds[i].getDeclaredType()
- != Object.class)
- code.checkcast().setType(fmds[i].getDeclaredType());
- } else {
- code.invokevirtual().setMethod(oidType, "getId",
- unwrapped, null);
- if (unwrapped != type)
- code.invokespecial().setMethod(type, "<init>",
- void.class, new Class[]{ unwrapped });
+ code.invokeinterface().setMethod(StateManager.class,
+ "getPCPrimaryKey", Object.class,
+ new Class[] { Object.class, int.class });
+ code.checkcast().setType(fmds[i].getDeclaredType());
+ } else {
+ unwrapped = (fmds[i].getDeclaredTypeCode() == JavaTypes.PC)
+ ? type : unwrapSingleFieldIdentity(fmds[i]);
+ if (fieldManager) {
+ code.aload().setParam(0);
+ code.constant().setValue(i);
+ code.getstatic().setField(INHERIT, int.class);
+ code.iadd();
+ } else
+ loadManagedInstance(code, false);
+
+ if (unwrapped != type) {
+ code.anew().setType(type);
+ code.dup();
}
- } else if (_meta.getAccessType() == ClassMetaData.ACCESS_FIELD)
- code.getfield().setField(findDeclaredField(oidType, name));
- else // property
- code.invokevirtual().setMethod(findDeclaredGetterMethod
- (oidType, StringUtils.capitalize(name)));
+ code.aload().setLocal(id);
+ if (_meta.isOpenJPAIdentity()) {
+ if (oidType == ObjectId.class) {
+ code.invokevirtual().setMethod(oidType, "getId",
+ Object.class, null);
+ if (!fieldManager && type != Object.class)
+ code.checkcast().setType(fmds[i].getDeclaredType());
+ } else {
+ code.invokevirtual().setMethod(oidType, "getId",
+ unwrapped, null);
+ if (unwrapped != type)
+ code.invokespecial().setMethod(type, "<init>",
+ void.class, new Class[]{ unwrapped });
+ }
+ } else if (_meta.getAccessType() == ClassMetaData.ACCESS_FIELD)
+ code.getfield().setField(findDeclaredField(oidType, name));
+ else // property
+ code.invokevirtual().setMethod(findDeclaredGetterMethod
+ (oidType, StringUtils.capitalize(name)));
+ }
if (fieldManager)
code.invokeinterface().setMethod(getFieldConsumerMethod(type));
@@ -1793,10 +1983,12 @@
loadManagedInstance(code, false);
FieldMetaData pk = _meta.getPrimaryKeyFields()[0];
addGetManagedValueCode(code, pk);
+ if (pk.getDeclaredTypeCode() == JavaTypes.PC)
+ addExtractObjectIdFieldValueCode(code, pk);
if (_meta.getObjectIdType() == ObjectId.class)
args = new Class[]{ Class.class, Object.class };
else
- args = new Class[]{ Class.class, pk.getDeclaredType() };
+ args = new Class[]{ Class.class, pk.getObjectIdFieldType() };
}
code.invokespecial().setMethod(oidType, "<init>", void.class, args);
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/StateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/StateManager.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/StateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/StateManager.java Fri Nov 3 15:15:08 2006
@@ -34,6 +34,13 @@
public Object getGenericContext();
/**
+ * Return the persistence-capable primary key object by extracting the
+ * identity value of the related instance stored in the given field from
+ * the given object id.
+ */
+ public Object getPCPrimaryKey(Object oid, int field);
+
+ /**
* Change internal flags.
*/
public byte replaceFlags();
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Fri Nov 3 15:15:08 2006
@@ -2761,7 +2761,7 @@
// refresh all
if (load != null) {
Collection failed = _store.loadAll(load, null,
- _store.FORCE_LOAD_REFRESH, _fc, null);
+ StoreManager.FORCE_LOAD_REFRESH, _fc, null);
if (failed != null && !failed.isEmpty())
exceps = add(exceps, newObjectNotFoundException(failed));
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java Fri Nov 3 15:15:08 2006
@@ -323,6 +323,10 @@
return PersistenceCapable.MEDIATE_WRITE;
}
+ public Object getPCPrimaryKey(Object oid, int field) {
+ throw new UnsupportedOperationException();
+ }
+
public StateManager replaceStateManager(StateManager sm) {
return sm;
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java Fri Nov 3 15:15:08 2006
@@ -399,6 +399,10 @@
return _ctx;
}
+ public Object getPCPrimaryKey(Object oid, int field) {
+ throw new UnsupportedOperationException();
+ }
+
public byte replaceFlags() {
throw new UnsupportedOperationException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java Fri Nov 3 15:15:08 2006
@@ -66,6 +66,10 @@
return (_owner == null) ? null : _owner.getGenericContext();
}
+ public Object getPCPrimaryKey(Object oid, int field) {
+ throw new UnsupportedOperationException();
+ }
+
public byte replaceFlags() {
throw new UnsupportedOperationException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Fri Nov 3 15:15:08 2006
@@ -215,9 +215,9 @@
}
}
- ///////////////////////////////////
+ //////////////////////////////////////
// OpenJPAStateManager implementation
- ///////////////////////////////////
+ //////////////////////////////////////
public void initialize(Class cls, PCState state) {
// check to see if our current object id instance is the
@@ -1302,6 +1302,22 @@
} catch (RuntimeException re) {
throw translate(re);
}
+ }
+
+ public Object getPCPrimaryKey(Object oid, int field) {
+ FieldMetaData fmd = _meta.getField(field);
+ Object pk = ApplicationIds.get(oid, fmd);
+ if (pk == null)
+ return null;
+
+ ClassMetaData relmeta = fmd.getDeclaredTypeMetaData();
+ if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE
+ && fmd.getObjectIdFieldTypeCode() == JavaTypes.LONG)
+ pk = _broker.getStoreManager().newDataStoreId(pk, relmeta);
+ else if (relmeta.getIdentityType() == ClassMetaData.ID_APPLICATION
+ && fmd.getObjectIdFieldType() != relmeta.getObjectIdType())
+ pk = ApplicationIds.fromPKValues(new Object[] { pk }, relmeta);
+ return _broker.find(pk, false, null);
}
public byte replaceFlags() {
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java Fri Nov 3 15:15:08 2006
@@ -45,6 +45,7 @@
private boolean _interface = true;
private boolean _pcRegistry = true;
private int _callback = CALLBACK_RETHROW;
+ private boolean _unwrapped = false;
/**
* Whether to attempt to use the information from registered classes
@@ -113,6 +114,22 @@
return false;
}
+ public boolean isDeclaredInterfacePersistent() {
+ return _interface;
+ }
+
+ public void setDeclaredInterfacePersistent(boolean pers) {
+ _interface = pers;
+ }
+
+ public boolean isDataStoreObjectIdFieldUnwrapped() {
+ return _unwrapped;
+ }
+
+ public void setDataStoreObjectIdFieldUnwrapped(boolean unwrapped) {
+ _unwrapped = unwrapped;
+ }
+
public boolean getIgnoreNonPersistent() {
return _ignore;
}
@@ -281,14 +298,6 @@
*/
protected abstract boolean isDefaultPersistent(ClassMetaData meta,
Member member, String name);
-
- public void setDeclaredInterfacePersistent(boolean pers) {
- _interface = pers;
- }
-
- public boolean isDeclaredInterfacePersistent() {
- return _interface;
- }
public Member getBackingMember(FieldMetaData fmd) {
if (fmd == null)
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Fri Nov 3 15:15:08 2006
@@ -428,7 +428,7 @@
FieldMetaData[] pks = getPrimaryKeyFields();
if (pks.length != 1)
return null;
- switch (pks[0].getDeclaredTypeCode()) {
+ switch (pks[0].getObjectIdFieldTypeCode()) {
case JavaTypes.BYTE:
case JavaTypes.BYTE_OBJ:
_objectId = ByteId.class;
@@ -456,6 +456,7 @@
_objectId = DateId.class;
break;
case JavaTypes.OID:
+ case JavaTypes.OBJECT:
_objectId = ObjectId.class;
break;
}
@@ -1898,29 +1899,32 @@
Method m;
String cap;
int type;
- Class comp;
+ Class c;
+ ClassMetaData idmeta;
int access = meta.getAccessType();
for (int i = 0; i < fmds.length; i++) {
switch (fmds[i].getDeclaredTypeCode()) {
case JavaTypes.ARRAY:
- comp = fmds[i].getDeclaredType().getComponentType();
- if (comp == byte.class || comp == Byte.class
- || comp == char.class || comp == Character.class)
+ c = fmds[i].getDeclaredType().getComponentType();
+ if (c == byte.class || c == Byte.class
+ || c == char.class || c == Character.class) {
+ c = fmds[i].getDeclaredType();
break;
+ }
// else no break
+ case JavaTypes.PC_UNTYPED:
case JavaTypes.COLLECTION:
case JavaTypes.MAP:
- case JavaTypes.PC:
- case JavaTypes.PC_UNTYPED:
case JavaTypes.OID: // we're validating embedded fields
throw new MetaDataException(_loc.get("bad-pk-type",
fmds[i]));
+ default:
+ c = fmds[i].getObjectIdFieldType();
}
if (access == ACCESS_FIELD) {
f = findField(oid, fmds[i].getName(), runtime);
- if (f == null || !f.getType().isAssignableFrom(fmds[i].
- getDeclaredType()))
+ if (f == null || !f.getType().isAssignableFrom(c))
throw new MetaDataException(_loc.get("invalid-id",
_type)).setFailedObject(fmds[i].getName());
} else if (access == ACCESS_PROPERTY) {
@@ -1931,8 +1935,7 @@
if (m == null && (type == JavaTypes.BOOLEAN
|| type == JavaTypes.BOOLEAN_OBJ))
m = findMethod(oid, "is" + cap, null, runtime);
- if (m == null || !m.getReturnType().
- isAssignableFrom(fmds[i].getDeclaredType()))
+ if (m == null || !m.getReturnType().isAssignableFrom(c))
throw new MetaDataException(_loc.get("invalid-id",
_type)).setFailedObject("get" + cap);
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java Fri Nov 3 15:15:08 2006
@@ -506,6 +506,48 @@
}
/**
+ * For a primary key field, return the type of the corresponding object id
+ * class field.
+ */
+ public int getObjectIdFieldTypeCode() {
+ ClassMetaData relmeta = getDeclaredTypeMetaData();
+ if (relmeta == null)
+ return getDeclaredTypeCode();
+ if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE) {
+ boolean unwrap = getRepository().getMetaDataFactory().getDefaults().
+ isDataStoreObjectIdFieldUnwrapped();
+ return (unwrap) ? JavaTypes.LONG : JavaTypes.OBJECT;
+ }
+ if (relmeta.isOpenJPAIdentity())
+ return relmeta.getPrimaryKeyFields()[0].getObjectIdFieldTypeCode();
+ return JavaTypes.OBJECT;
+ }
+
+ /**
+ * For a primary key field, return the type of the corresponding object id
+ * class field.
+ */
+ public Class getObjectIdFieldType() {
+ ClassMetaData relmeta = getDeclaredTypeMetaData();
+ if (relmeta == null)
+ return getDeclaredType();
+ switch (relmeta.getIdentityType()) {
+ case ClassMetaData.ID_DATASTORE:
+ boolean unwrap = getRepository().getMetaDataFactory().
+ getDefaults().isDataStoreObjectIdFieldUnwrapped();
+ return (unwrap) ? long.class : Object.class;
+ case ClassMetaData.ID_APPLICATION:
+ if (relmeta.isOpenJPAIdentity())
+ return relmeta.getPrimaryKeyFields()[0].
+ getObjectIdFieldType();
+ return (relmeta.getObjectIdType() == null) ? Object.class
+ : relmeta.getObjectIdType();
+ default:
+ return Object.class;
+ }
+ }
+
+ /**
* Whether this field holds optimistic version information.
*/
public boolean isVersion() {
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java Fri Nov 3 15:15:08 2006
@@ -49,18 +49,25 @@
* event type. Defaults to false.
*/
public boolean getCallbacksBeforeListeners(int type);
-
- /**
- * Whether to ignore members which are not persistent by default
- * during metadata population. Defaults to true.
- */
- public void setIgnoreNonPersistent(boolean ignore);
-
+
/**
* Whether declared interfaces of a class are treated as persistent
* types. Defaults to true.
*/
public boolean isDeclaredInterfacePersistent();
+
+ /**
+ * Whether the field in the object id class corresponding to a
+ * datastore id persistence-capable primary key field is the simple
+ * datastore id value of the related instance. Defaults to false.
+ */
+ public boolean isDataStoreObjectIdFieldUnwrapped();
+
+ /**
+ * Whether to ignore members which are not persistent by default
+ * during metadata population. Defaults to true.
+ */
+ public void setIgnoreNonPersistent(boolean ignore);
/**
* Populate the given metadata with default settings.
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataInheritanceComparator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataInheritanceComparator.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataInheritanceComparator.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataInheritanceComparator.java Fri Nov 3 15:15:08 2006
@@ -16,7 +16,8 @@
package org.apache.openjpa.meta;
/**
- * Comparator that keeps metadatas in inheritance order.
+ * Comparator that keeps metadatas in inheritance order. Also places relation
+ * types used as primary keys before the primary key field owner types.
*
* @author Abe White
* @nojavadoc
@@ -28,5 +29,31 @@
if (elem == null)
return null;
return ((ClassMetaData) elem).getDescribedType();
+ }
+
+ public int compare(Object o1, Object o2) {
+ if (o1 == o2)
+ return 0;
+ if (o1 == null)
+ return -1;
+ if (o2 == null)
+ return 1;
+
+ ClassMetaData m1 = (ClassMetaData) o1;
+ ClassMetaData m2 = (ClassMetaData) o2;
+
+ FieldMetaData[] fmds = m1.getDeclaredFields();
+ for (int i = 0; i < fmds.length; i++) {
+ if (fmds[i].isPrimaryKey() && m2.getDescribedType().
+ isAssignableFrom(fmds[i].getDeclaredType()))
+ return 1;
+ }
+ fmds = m2.getDeclaredFields();
+ for (int i = 0; i < fmds.length; i++) {
+ if (fmds[i].isPrimaryKey() && m1.getDescribedType().
+ isAssignableFrom(fmds[i].getDeclaredType()))
+ return -1;
+ }
+ return super.compare(o1, o2);
}
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Fri Nov 3 15:15:08 2006
@@ -483,6 +483,8 @@
// load mapping data
for (int i = 0; i < resolved.size(); i++)
loadMapping((ClassMetaData) resolved.get(i));
+ for (int i = 0; i < resolved.size(); i++)
+ preMapping((ClassMetaData) resolved.get(i));
// resolve mappings
boolean err = true;
@@ -499,7 +501,6 @@
re = new MetaDataException(_loc.get("resolve-errs")).
setNestedThrowables((Throwable[]) _errs.toArray
(new Exception[_errs.size()]));
- ;
_errs.clear();
throw re;
}
@@ -540,6 +541,13 @@
meta.getPCSuperclass()));
}
+ // resolve relation primary key fields for mapping dependencies
+ FieldMetaData[] fmds = meta.getDeclaredFields();
+ for (int i = 0; i < fmds.length; i++)
+ if (fmds[i].isPrimaryKey())
+ getMetaData(fmds[i].getDeclaredType(),
+ meta.getEnvClassLoader(), false);
+
// resolve metadata; if we're not in the process of resolving
// others, this will return the set of interrelated metas that
// resolved
@@ -571,10 +579,17 @@
} catch (RuntimeException re) {
removeMetaData(meta);
_errs.add(re);
- return;
}
}
}
+ }
+
+ /**
+ * Pre-mapping preparation.
+ */
+ private void preMapping(ClassMetaData meta) {
+ if ((meta.getResolve() & MODE_MAPPING) != 0)
+ return;
// prepare mappings for resolve; if not resolving mappings, then
// make sure any superclass fields defined in metadata are resolved
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java Fri Nov 3 15:15:08 2006
@@ -112,6 +112,10 @@
return false;
}
+ public boolean isDataStoreObjectIdFieldUnwrapped() {
+ return false;
+ }
+
public void populate(ClassMetaData meta, int access) {
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ProxySetupStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ProxySetupStateManager.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ProxySetupStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ProxySetupStateManager.java Fri Nov 3 15:15:08 2006
@@ -81,6 +81,10 @@
}
}
+ public Object getPCPrimaryKey(Object oid, int field) {
+ throw new UnsupportedOperationException();
+ }
+
public byte replaceFlags() {
throw new InternalException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java?view=diff&rev=471045&r1=471044&r2=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java Fri Nov 3 15:15:08 2006
@@ -44,6 +44,9 @@
/**
* Return the primary key values for the given object id. The values
* will be returned in the same order as the metadata primary key fields.
+ * Values for PC primary key fields will be the primarky key value or
+ * oid value of the related instance (depending on
+ * {@link FieldMetaData#isObjectIdFieldIdOfPC}).
*/
public static Object[] toPKValues(Object oid, ClassMetaData meta) {
if (meta == null)
@@ -88,8 +91,7 @@
if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD) {
field = oidType.getField(fmds[i].getName());
pks[i] = field.get(oid);
- } else // property
- {
+ } else { // property
meth = ImplHelper.getGetter(oidType, fmds[i].getName());
pks[i] = meth.invoke(oid, (Object[]) null);
}
@@ -104,6 +106,9 @@
/**
* Return a new object id constructed from the given primary key values.
+ * Values for PC primary key fields should be the primarky key value or
+ * oid value of the related instance (depending on
+ * {@link FieldMetaData#isObjectIdFieldIdOfPC}).
*/
public static Object fromPKValues(Object[] pks, ClassMetaData meta) {
if (meta == null || pks == null)
@@ -112,7 +117,7 @@
boolean convert = !meta.getRepository().getConfiguration().
getCompatibilityInstance().getStrictIdentityValues();
if (meta.isOpenJPAIdentity()) {
- int type = meta.getPrimaryKeyFields()[0].getDeclaredTypeCode();
+ int type = meta.getPrimaryKeyFields()[0].getObjectIdFieldTypeCode();
Object val = (convert) ? JavaTypes.convert(pks[0], type) : pks[0];
switch (type) {
case JavaTypes.BYTE:
@@ -148,6 +153,7 @@
case JavaTypes.DATE:
return new DateId(meta.getDescribedType(), (Date) val);
case JavaTypes.OID:
+ case JavaTypes.OBJECT:
return new ObjectId(meta.getDescribedType(), val);
default:
throw new InternalException();
@@ -182,9 +188,8 @@
if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD) {
field = oidType.getField(fmds[i].getName());
field.set(copy, (convert) ? JavaTypes.convert(pks[i],
- fmds[i].getDeclaredTypeCode()) : pks[i]);
- } else // property
- {
+ fmds[i].getObjectIdFieldTypeCode()) : pks[i]);
+ } else { // property
if (paramTypes == null)
paramTypes = new Class[1];
paramTypes[0] = fmds[i].getDeclaredType();
@@ -193,7 +198,7 @@
if (params == null)
params = new Object[1];
params[0] = (convert) ? JavaTypes.convert(pks[i],
- fmds[i].getDeclaredTypeCode()) : pks[i];
+ fmds[i].getObjectIdFieldTypeCode()) : pks[i];
meth.invoke(copy, params);
}
}
@@ -218,7 +223,7 @@
Class cls = meta.getDescribedType();
OpenJPAId koid = (OpenJPAId) oid;
FieldMetaData pk = meta.getPrimaryKeyFields()[0];
- switch (pk.getDeclaredTypeCode()) {
+ switch (pk.getObjectIdFieldTypeCode()) {
case JavaTypes.BYTE:
case JavaTypes.BYTE_OBJ:
return new ByteId(cls, ((ByteId) oid).getId(),
@@ -248,6 +253,9 @@
if (embed != null)
inner = copy(inner, embed, embed.getFields());
return new ObjectId(cls, inner, koid.hasSubclasses());
+ case JavaTypes.OBJECT:
+ return new ObjectId(cls, koid.getIdObject(),
+ koid.hasSubclasses());
default:
throw new InternalException();
}
@@ -256,10 +264,11 @@
// create a new pc instance of the right type, set its key fields
// to the original oid values, then copy its key fields to a new
// oid instance
- if (!Modifier.isAbstract(meta.getDescribedType().getModifiers())) {
- Class type = meta.getDescribedType();
- if (meta.getInterfaceImpl() != null)
- type = meta.getInterfaceImpl();
+ if (!Modifier.isAbstract(meta.getDescribedType().getModifiers())
+ && !hasPCPrimaryKeyFields(meta)) {
+ Class type = meta.getInterfaceImpl();
+ if (type == null)
+ type = meta.getDescribedType();
PersistenceCapable pc = PCRegistry.newInstance(type, null, oid,
false);
Object copy = pc.pcNewObjectIdInstance();
@@ -277,6 +286,18 @@
}
/**
+ * Return true if any of the given type's primary key fields are
+ * persistent objects.
+ */
+ private static boolean hasPCPrimaryKeyFields(ClassMetaData meta) {
+ FieldMetaData[] fmds = meta.getPrimaryKeyFields();
+ for (int i = 0; i < fmds.length; i++)
+ if (fmds[i].getDeclaredTypeCode() == JavaTypes.PC)
+ return true;
+ return false;
+ }
+
+ /**
* Copy the given identity object using reflection.
*/
private static Object copy(Object oid, ClassMetaData meta,
@@ -284,7 +305,6 @@
if (oid == null)
return null;
- // default to using reflection
Class oidType = oid.getClass();
try {
Object copy = oidType.newInstance();
@@ -300,11 +320,10 @@
if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD) {
field = oidType.getField(fmds[i].getName());
field.set(copy, field.get(oid));
- } else // property
- {
+ } else { // property
if (paramTypes == null)
paramTypes = new Class[1];
- paramTypes[0] = fmds[i].getDeclaredType();
+ paramTypes[0] = fmds[i].getObjectIdFieldType();
cap = StringUtils.capitalize(fmds[i].getName());
meth = oidType.getMethod("set" + cap, paramTypes);
if (params == null)
@@ -323,6 +342,32 @@
}
/**
+ * Return the given primary key field value from the given oid.
+ */
+ public static Object get(Object oid, FieldMetaData fmd) {
+ if (oid == null)
+ return null;
+ if (oid instanceof OpenJPAId)
+ return ((OpenJPAId) oid).getIdObject();
+
+ ClassMetaData meta = fmd.getDefiningMetaData();
+ Class oidType = oid.getClass();
+ try {
+ if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD)
+ return oidType.getField(fmd.getName()).get(oid);
+
+ // property
+ String cap = StringUtils.capitalize(fmd.getName());
+ return ImplHelper.getGetter(oidType, cap).
+ invoke(oid, (Object[]) null);
+ } catch (OpenJPAException ke) {
+ throw ke;
+ } catch (Throwable t) {
+ throw new GeneralException(t);
+ }
+ }
+
+ /**
* Generate an application id based on the current primary key field state
* of the given instance.
*/
@@ -502,9 +547,14 @@
private Object retrieve(int field) {
Object val = _store[_index++];
- if (_meta != null)
- val = JavaTypes.convert(val, _meta.getField(field).
- getDeclaredTypeCode());
+ if (_meta != null) {
+ FieldMetaData fmd = _meta.getField(field);
+ if (fmd.getDeclaredTypeCode() != JavaTypes.PC)
+ val = JavaTypes.convert(val, fmd.getDeclaredTypeCode());
+ else
+ val = JavaTypes.convert(val, JavaTypes.getTypeCode(fmd.
+ getObjectIdFieldType()));
+ }
return val;
}
}
Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java?view=auto&rev=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java Fri Nov 3 15:15:08 2006
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class BasicEntity {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ @ManyToOne
+ private BasicEntity rel;
+
+ @Version
+ private Integer optLock;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public BasicEntity getRel() {
+ return rel;
+ }
+
+ public void setRel(BasicEntity rel) {
+ this.rel = rel;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java?view=auto&rev=471045
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java Fri Nov 3 15:15:08 2006
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.DataStoreId;
+
+@Entity
+@DataStoreId
+public class DataStoreBasicEntity {
+
+ private String name;
+
+ @ManyToOne
+ private BasicEntity rel;
+
+ @Version
+ private Integer optLock;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public BasicEntity getRel() {
+ return rel;
+ }
+
+ public void setRel(BasicEntity rel) {
+ this.rel = rel;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java
------------------------------------------------------------------------------
svn:executable = *