Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (revision 566001) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (working copy) @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Set; +import org.apache.commons.lang.StringUtils; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy; @@ -189,8 +190,34 @@ } } Object oid = ApplicationIds.fromPKValues(vals, cls); - if (!subs && oid instanceof OpenJPAId) - ((OpenJPAId) oid).setManagedInstanceType(cls.getDescribedType()); + + /** + * For polymorphic relations, + * the type field in the oid is initially set to base type. + * If the discriminator value is preset in the current result, + * then the type field needs reset based on the discriminator value. + * If the discriminator value is not present or invalid, + * ignore any exceptions being thrown. + */ + if (oid instanceof OpenJPAId) { + Class type = cls.getDescribedType(); + if (!subs) + // non-polymorphic relations + ((OpenJPAId) oid).setManagedInstanceType(type); + else if (cls.getDiscriminator() != null + && !StringUtils.equals("none", + cls.getDiscriminator().getStrategy().getAlias())) { + // polymorphic relations + res.startDataRequest(cls.getDiscriminator()); + try { + type = cls.getDiscriminator().getClass(store, cls, res); + ((OpenJPAId) oid).setManagedInstanceType(type, true); + } catch (Exception e) { + // intentionally ignored + } + res.endDataRequest(); + } + } return oid; } Index: openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java =================================================================== --- openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java (revision 566001) +++ openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java (working copy) @@ -78,6 +78,14 @@ } /** + * Set the exact type of the described instance once it is known. + */ + public void setManagedInstanceType(Class type, boolean subs) { + this.type = type; + this.subs = subs; + } + + /** * Return the identity value as an object. */ public abstract Object getIdObject();