diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java index cc6ddc888..38de37923 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java @@ -30,6 +30,7 @@ import java.util.List; 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 @@ public class ClassMapping } } 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; } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java index 9e0347659..2b64a4e35 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java @@ -77,6 +77,14 @@ public abstract class OpenJPAId this.subs = false; } + /** + * 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. */