diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java index 10d0540df..bd54efbb8 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java @@ -4940,7 +4940,7 @@ public class BrokerImpl * Unique id for state managers of new datastore instances without assigned * object ids. */ - private static class StateManagerId + public static class StateManagerId implements Serializable { public static final String STRING_PREFIX = "openjpasm:"; diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java index 57ca5f358..7929f6bc6 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java @@ -169,6 +169,7 @@ public class ClassMetaData //////////////////////////////////////////////////////////////////// private Class _objectId = null; + private Class _idClass = null; private Boolean _objectIdShared = null; private Boolean _openjpaId = null; private Boolean _extent = null; @@ -574,6 +575,7 @@ public class ClassMetaData setIdentityType(ID_APPLICATION); if (!OpenJPAId.class.isAssignableFrom(cls)) { _objectId = cls; + _idClass = cls; _objectIdShared = (shared) ? Boolean.TRUE : Boolean.FALSE; } } @@ -2506,6 +2508,7 @@ public class ClassMetaData // lazy data _super = meta.getPCSuperclass(); _objectId = meta.getObjectIdType(); + _idClass = meta.getIdClass(); _extent = (meta.getRequiresExtent()) ? Boolean.TRUE : Boolean.FALSE; _embedded = (meta.isEmbeddedOnly()) ? Boolean.TRUE : Boolean.FALSE; _embeddable = meta._embeddable; @@ -2768,5 +2771,12 @@ public class ClassMetaData public String getSourceName(){ return _srcName; } + + /** + * The class specified with the @IdClass annotation if used + */ + public Class getIdClass() { + return _idClass; + } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestJPAFacadeHelper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestJPAFacadeHelper.java index f03ac207f..04a4cd5b1 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestJPAFacadeHelper.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/util/TestJPAFacadeHelper.java @@ -18,9 +18,16 @@ */ package org.apache.openjpa.persistence.util; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Date; import java.util.ArrayList; import java.util.Collection; +import javax.persistence.EntityManager; + +import org.apache.openjpa.enhance.PersistenceCapable; +import org.apache.openjpa.kernel.StateManagerImpl; import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.MetaDataRepository; import org.apache.openjpa.persistence.JPAFacadeHelper; @@ -35,23 +42,39 @@ import org.apache.openjpa.persistence.derivedid.EDDateID; import org.apache.openjpa.persistence.derivedid.EDSQLDateID; import org.apache.openjpa.persistence.derivedid.EDateID; import org.apache.openjpa.persistence.derivedid.ESQLDateID; +import org.apache.openjpa.persistence.enhance.identity.Book; +import org.apache.openjpa.persistence.enhance.identity.BookId; +import org.apache.openjpa.persistence.enhance.identity.Library; +import org.apache.openjpa.persistence.enhance.identity.MedicalHistory4; +import org.apache.openjpa.persistence.enhance.identity.Page; +import org.apache.openjpa.persistence.enhance.identity.Person4; +import org.apache.openjpa.persistence.enhance.identity.PersonId4; +import org.apache.openjpa.persistence.identity.BooleanIdEntity; +import org.apache.openjpa.persistence.identity.DoubleObjIdEntity; +import org.apache.openjpa.persistence.identity.FloatIdEntity; +import org.apache.openjpa.persistence.identity.SQLBigDecimalIdEntity; +import org.apache.openjpa.persistence.identity.SQLBigIntegerIdEntity; +import org.apache.openjpa.persistence.identity.SQLDateIdEntity; +import org.apache.openjpa.persistence.identity.StringIdEntity; +import org.apache.openjpa.persistence.identity.entityasidentity.Person; import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.CompositeId; import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.EntityWithCompositeId; import org.apache.openjpa.persistence.relations.BasicEntity; import org.apache.openjpa.persistence.simple.AllFieldTypes; import org.apache.openjpa.persistence.test.SingleEMFTestCase; import org.apache.openjpa.util.Id; -import org.apache.openjpa.util.LongId; -import org.apache.openjpa.util.ObjectId; import org.apache.openjpa.util.UserException; public class TestJPAFacadeHelper extends SingleEMFTestCase { MetaDataRepository repo = null; public void setUp() { - setUp(EmbeddedIdEntity.class, EmbeddedIdClass.class, EBigDecimalID.class, EDBigDecimalID.class, + setUp(CLEAR_TABLES, EmbeddedIdEntity.class, EmbeddedIdClass.class, EBigDecimalID.class, EDBigDecimalID.class, EBigIntegerID.class, EDBigIntegerID.class, EDateID.class, EDDateID.class, ESQLDateID.class, - EDSQLDateID.class, EntityWithCompositeId.class, AllFieldTypes.class, BasicEntity.class); + EDSQLDateID.class, EntityWithCompositeId.class, AllFieldTypes.class, BasicEntity.class, Book.class, + Library.class, Page.class, Person.class, DoubleObjIdEntity.class, FloatIdEntity.class, + BooleanIdEntity.class, StringIdEntity.class, SQLBigIntegerIdEntity.class, SQLDateIdEntity.class, + SQLBigDecimalIdEntity.class, MedicalHistory4.class, Person4.class, PersonId4.class); repo = emf.getConfiguration().getMetaDataRepositoryInstance(); } @@ -63,10 +86,27 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase { fail("Didn't fail!"); } catch (UserException re) { // expected - } + + // Initialize and persist entity EmbeddedIdClass id = new EmbeddedIdClass(); - assertEquals(ObjectId.class, JPAFacadeHelper.toOpenJPAObjectId(cmd, id).getClass()); + id.setPk1(1); + id.setPk2(2); + EmbeddedIdEntity entity = new EmbeddedIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + // Find the entity and retrieve the objectId we use internally + EmbeddedIdEntity persistedEntity = em.find(EmbeddedIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); } public void testCompositeId() throws Exception { @@ -76,10 +116,25 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase { fail("Didn't fail!"); } catch (UserException re) { // expected - } - CompositeId id = new CompositeId(12, "name"); - assertEquals(ObjectId.class, JPAFacadeHelper.toOpenJPAObjectId(cmd, id).getClass()); + int intId = 1; + String nameId = "CompositeEntity"; + EntityWithCompositeId entity = new EntityWithCompositeId(); + entity.setId(intId); + entity.setName(nameId); + CompositeId id = new CompositeId(intId, nameId); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + EntityWithCompositeId persistedEntity = em.find(EntityWithCompositeId.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); } public void testBasic() throws Exception { @@ -95,13 +150,235 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase { fail("Didn't fail!"); } catch (UserException re) { // expected - } - assertEquals(LongId.class, JPAFacadeHelper.toOpenJPAObjectId(cmd, Long.valueOf(1)).getClass()); - Object o = JPAFacadeHelper.toOpenJPAObjectId(cmd, Long.valueOf(1)); + + BasicEntity entity = new BasicEntity(); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + // Find the entity and retrieve the objectId we use internally + BasicEntity persistedEntity = em.find(BasicEntity.class, entity.getId()); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, entity.getId())); + Object o = JPAFacadeHelper.toOpenJPAObjectId(cmd, entity.getId()); assertEquals(o, JPAFacadeHelper.toOpenJPAObjectId(cmd, o)); } + public void testIntegerId() { + ClassMetaData cmd = repo.getMetaData(Person.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new Person()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + Integer id = Integer.valueOf(1); + Person entity = new Person(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + Person persistedEntity = em.find(Person.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testDoubleId() { + ClassMetaData cmd = repo.getMetaData(DoubleObjIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new DoubleObjIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + Double id = Double.valueOf(1); + DoubleObjIdEntity entity = new DoubleObjIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + DoubleObjIdEntity persistedEntity = em.find(DoubleObjIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testFloatId() { + ClassMetaData cmd = repo.getMetaData(FloatIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new FloatIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + Float id = Float.valueOf(1); + FloatIdEntity entity = new FloatIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + FloatIdEntity persistedEntity = em.find(FloatIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testBooleanId() { + ClassMetaData cmd = repo.getMetaData(BooleanIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new BooleanIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + Boolean id = Boolean.valueOf(true); + BooleanIdEntity entity = new BooleanIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + BooleanIdEntity persistedEntity = em.find(BooleanIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testStringId() { + ClassMetaData cmd = repo.getMetaData(StringIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new StringIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + String id = "StringId"; + StringIdEntity entity = new StringIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + StringIdEntity persistedEntity = em.find(StringIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testBigIntegerId() { + ClassMetaData cmd = repo.getMetaData(SQLBigIntegerIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new SQLBigIntegerIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + BigInteger id = BigInteger.valueOf(1); + SQLBigIntegerIdEntity entity = new SQLBigIntegerIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + SQLBigIntegerIdEntity persistedEntity = em.find(SQLBigIntegerIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testBigDecimalId() { + ClassMetaData cmd = repo.getMetaData(SQLBigDecimalIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new SQLBigDecimalIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + BigDecimal id = BigDecimal.valueOf(1); + SQLBigDecimalIdEntity entity = new SQLBigDecimalIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + SQLBigDecimalIdEntity persistedEntity = em.find(SQLBigDecimalIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testDateId() { + ClassMetaData cmd = repo.getMetaData(SQLDateIdEntity.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new SQLDateIdEntity()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + long time = ((long) (System.currentTimeMillis() / 1000)) * 1000; + Date id = new Date(time); + SQLDateIdEntity entity = new SQLDateIdEntity(); + entity.setId(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + SQLDateIdEntity persistedEntity = em.find(SQLDateIdEntity.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + public void testDerivedId() throws Exception { ClassMetaData cmd = repo.getMetaData(EDSQLDateID.class, null, true); try { @@ -109,16 +386,94 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase { fail("Didn't fail!"); } catch (UserException re) { // expected - } - ESQLDateID id = new ESQLDateID(); - assertEquals(ObjectId.class, JPAFacadeHelper.toOpenJPAObjectId(cmd, id).getClass()); + + Date d = new Date(2014, 3, 26); + ESQLDateID id = new ESQLDateID(d); + EDSQLDateID entity = new EDSQLDateID(id); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(id); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + EDSQLDateID persistedEntity = em.find(EDSQLDateID.class, d); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, d)); + } + + public void testCompositeDerivedId() throws Exception { + ClassMetaData cmd = repo.getMetaData(Book.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new Book()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + String bookName = "Harry Potter"; + String libName = "Library Name"; + Library entity = new Library(); + entity.setName(libName); + Book book = new Book(); + book.setName(bookName); + entity.addBook(book); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + BookId id = new BookId(); + id.setName(bookName); + id.setLibrary(libName); + + Book persistedEntity = em.find(Book.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); + } + + public void testCompositeDerivedEmbeddedId() { + ClassMetaData cmd = repo.getMetaData(MedicalHistory4.class, null, true); + try { + JPAFacadeHelper.toOpenJPAObjectId(cmd, new MedicalHistory4()); + fail("Didn't fail!"); + } catch (UserException re) { + // expected + } + + PersonId4 id = new PersonId4("First", "Last"); + Person4 person = new Person4(); + person.setId(id); + MedicalHistory4 entity = new MedicalHistory4(); + entity.setPatient(person); + entity.setName("MedicalHistory"); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(person); + em.persist(entity); + em.getTransaction().commit(); + em.clear(); + + MedicalHistory4 persistedEntity = em.find(MedicalHistory4.class, id); + StateManagerImpl smi = ((StateManagerImpl) ((PersistenceCapable) persistedEntity).pcGetStateManager()); + Object oid = smi.getObjectId(); + + assertEquals(oid, JPAFacadeHelper.toOpenJPAObjectId(cmd, id)); } public void testNoId() throws Exception { ClassMetaData cmd = repo.getMetaData(AllFieldTypes.class, null, true); try { - // Don't parameterize this collection to force the JVM to use the + // Don't parameterize this collection to force the JVM to use the // ...(ClassMetaData meta, Collection oids) method sig. Collection ids = new ArrayList(); ids.add(new AllFieldTypes()); @@ -126,14 +481,12 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase { fail("Didn't fail!"); } catch (UserException re) { // expected - } try { JPAFacadeHelper.toOpenJPAObjectId(cmd, "a"); fail("Didn't fail!"); } catch (UserException re) { // expected - } OpenJPAEntityManagerSPI em = emf.createEntityManager(); em.getTransaction().begin(); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java index 5e44b41e3..c836c58f3 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java @@ -18,6 +18,7 @@ */ package org.apache.openjpa.persistence; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; @@ -26,23 +27,28 @@ import java.util.Collection; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import org.apache.openjpa.enhance.PCRegistry; import org.apache.openjpa.kernel.Broker; import org.apache.openjpa.kernel.BrokerFactory; +import org.apache.openjpa.kernel.BrokerImpl.StateManagerId; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.ValueMetaData; +import org.apache.openjpa.util.ApplicationIds; import org.apache.openjpa.util.BigDecimalId; import org.apache.openjpa.util.BigIntegerId; import org.apache.openjpa.util.ByteId; import org.apache.openjpa.util.CharId; import org.apache.openjpa.util.DoubleId; import org.apache.openjpa.util.FloatId; +import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.Id; import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.IntId; import org.apache.openjpa.util.LongId; import org.apache.openjpa.util.ObjectId; +import org.apache.openjpa.util.OpenJPAException; import org.apache.openjpa.util.OpenJPAId; import org.apache.openjpa.util.ShortId; import org.apache.openjpa.util.StringId; @@ -221,64 +227,62 @@ public class JPAFacadeHelper { if (oid instanceof OpenJPAId) { return oid; } + Class cls = meta.getDescribedType(); - Class oidType = meta.getObjectIdType(); FieldMetaData[] pks = meta.getPrimaryKeyFields(); - Object expected = oidType; - Object actual = oid.getClass(); - - // embedded id and derived id - if (pks.length > 0 && (pks[0].isEmbedded() || pks[0].isTypePC())) { - if (pks[0].getDeclaredType().equals(oid.getClass())) { - return new ObjectId(cls, oid); - } - expected = pks[0].getDeclaredType(); - } - if (oidType != null && oidType.equals(oid.getClass())) { - // Check for compound id class - return new ObjectId(cls, oid); - } - if (meta.getIdentityType() == ClassMetaData.ID_DATASTORE) { - // no id field - try { + Object expected = meta.getObjectIdType(); + try { + switch (meta.getIdentityType()) { + case ClassMetaData.ID_DATASTORE: + if (oid instanceof String && ((String) oid).startsWith(StateManagerId.STRING_PREFIX)) + return new StateManagerId((String) oid); return new Id(cls, ((Number) oid).longValue()); - } catch (ClassCastException cce) { - // swallow, the proper exception will be thrown below - expected = Number.class; + case ClassMetaData.ID_APPLICATION: + if (ImplHelper.isAssignable(meta.getObjectIdType(), oid.getClass())) { + if (!meta.isOpenJPAIdentity() && meta.isObjectIdTypeShared()) + return new ObjectId(cls, oid); + return oid; + } + + if (meta.getIdClass() == null) { + expected = pks[0].getDeclaredType(); + } else { + expected = meta.getIdClass(); + } + // stringified app id? + if (oid instanceof String + && !meta.getRepository().getConfiguration().getCompatibilityInstance().getStrictIdentityValues() + && !Modifier.isAbstract(cls.getModifiers())) + return PCRegistry.newObjectId(cls, (String) oid); + + Object[] arr = (oid instanceof Object[]) ? (Object[]) oid : new Object[] { oid }; + Object rtrn = ApplicationIds.fromPKValues(arr, meta); + if (rtrn != null && meta.getObjectIdType() != null) { + if (rtrn instanceof ObjectId) { + // embedded id and composite id with a derived id that + // uses an embedded id + if (pks.length > 0 && (pks[0].isEmbedded() || pks[0].isTypePC())) { + Class idClass = meta.getIdClass(); + if (pks[0].getDeclaredType().equals(oid.getClass()) || idClass != null + && idClass.equals(oid.getClass())) { + return rtrn; + } + } + } else { + if (!(rtrn instanceof StringId) || rtrn instanceof StringId && oid instanceof String) { + return rtrn; + } + } + } + default: + throw new UserException(_loc.get("invalid-oid", new Object[] { expected, oid.getClass() })); } + } catch (RuntimeException re) { + if (expected == null) + throw new UserException(_loc.get("invalid-oid", new Object[] { Number.class, oid.getClass() })); + throw new UserException(_loc.get("invalid-oid", new Object[] { expected, oid.getClass() })); } - if (pks.length > 0) { - Class pkType = pks[0].getDeclaredType(); - try { - // Check for basic types, cast provided object to expected type. Catch CCE for invalid input - if (pkType.equals(Byte.class) || pkType.equals(byte.class)) - return new ByteId(cls, (Byte) oid); - if (pkType.equals(Character.class) || pkType.equals(char.class)) - return new CharId(cls, (Character) oid); - if (pkType.equals(Double.class) || pkType.equals(double.class)) - return new DoubleId(cls, (Double) oid); - if (pkType.equals(Float.class) || pkType.equals(float.class)) - return new FloatId(cls, (Float) oid); - if (pkType.equals(Integer.class) || pkType.equals(int.class)) - return new IntId(cls, (Integer) oid); - if (pkType.equals(Long.class) || pkType.equals(long.class)) - return new LongId(cls, (Long) oid); - if (pkType.equals(Short.class) || pkType.equals(short.class)) - return new ShortId(cls, (Short) oid); - if (pkType.equals(String.class)) - return new StringId(cls, (String) oid); - if (pkType.equals(BigDecimal.class)) - return new BigDecimalId(cls, (BigDecimal) oid); - if (pkType.equals(BigInteger.class)) - return new BigIntegerId(cls, (BigInteger) oid); - } catch (ClassCastException cce) { - // swallow, the proper exception will be thrown below - expected = pkType; - } - } - // At this point we don't have a basic ID field, we don't have an embedded or composite id. fail. - throw new UserException(_loc.get("invalid-oid", new Object[] { expected, actual })); } /**