OPENJPA-2506: StoreCache interface doesn't work for many ID types - back ported Dalia's fix to 2.1.x.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/2.1.x@1648430 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Heath Thomann 2014-12-29 21:01:02 +00:00
parent 1318c6924e
commit e14f922149
4 changed files with 438 additions and 71 deletions

View File

@ -4940,7 +4940,7 @@ public class BrokerImpl
* Unique id for state managers of new datastore instances without assigned * Unique id for state managers of new datastore instances without assigned
* object ids. * object ids.
*/ */
private static class StateManagerId public static class StateManagerId
implements Serializable { implements Serializable {
public static final String STRING_PREFIX = "openjpasm:"; public static final String STRING_PREFIX = "openjpasm:";

View File

@ -169,6 +169,7 @@ public class ClassMetaData
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
private Class<?> _objectId = null; private Class<?> _objectId = null;
private Class<?> _idClass = null;
private Boolean _objectIdShared = null; private Boolean _objectIdShared = null;
private Boolean _openjpaId = null; private Boolean _openjpaId = null;
private Boolean _extent = null; private Boolean _extent = null;
@ -574,6 +575,7 @@ public class ClassMetaData
setIdentityType(ID_APPLICATION); setIdentityType(ID_APPLICATION);
if (!OpenJPAId.class.isAssignableFrom(cls)) { if (!OpenJPAId.class.isAssignableFrom(cls)) {
_objectId = cls; _objectId = cls;
_idClass = cls;
_objectIdShared = (shared) ? Boolean.TRUE : Boolean.FALSE; _objectIdShared = (shared) ? Boolean.TRUE : Boolean.FALSE;
} }
} }
@ -2506,6 +2508,7 @@ public class ClassMetaData
// lazy data // lazy data
_super = meta.getPCSuperclass(); _super = meta.getPCSuperclass();
_objectId = meta.getObjectIdType(); _objectId = meta.getObjectIdType();
_idClass = meta.getIdClass();
_extent = (meta.getRequiresExtent()) ? Boolean.TRUE : Boolean.FALSE; _extent = (meta.getRequiresExtent()) ? Boolean.TRUE : Boolean.FALSE;
_embedded = (meta.isEmbeddedOnly()) ? Boolean.TRUE : Boolean.FALSE; _embedded = (meta.isEmbeddedOnly()) ? Boolean.TRUE : Boolean.FALSE;
_embeddable = meta._embeddable; _embeddable = meta._embeddable;
@ -2768,5 +2771,12 @@ public class ClassMetaData
public String getSourceName(){ public String getSourceName(){
return _srcName; return _srcName;
} }
/**
* The class specified with the @IdClass annotation if used
*/
public Class<?> getIdClass() {
return _idClass;
}
} }

View File

@ -18,9 +18,16 @@
*/ */
package org.apache.openjpa.persistence.util; 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.ArrayList;
import java.util.Collection; 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.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository; import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.JPAFacadeHelper; 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.EDSQLDateID;
import org.apache.openjpa.persistence.derivedid.EDateID; import org.apache.openjpa.persistence.derivedid.EDateID;
import org.apache.openjpa.persistence.derivedid.ESQLDateID; 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.CompositeId;
import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.EntityWithCompositeId; import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.EntityWithCompositeId;
import org.apache.openjpa.persistence.relations.BasicEntity; import org.apache.openjpa.persistence.relations.BasicEntity;
import org.apache.openjpa.persistence.simple.AllFieldTypes; import org.apache.openjpa.persistence.simple.AllFieldTypes;
import org.apache.openjpa.persistence.test.SingleEMFTestCase; import org.apache.openjpa.persistence.test.SingleEMFTestCase;
import org.apache.openjpa.util.Id; import org.apache.openjpa.util.Id;
import org.apache.openjpa.util.LongId;
import org.apache.openjpa.util.ObjectId;
import org.apache.openjpa.util.UserException; import org.apache.openjpa.util.UserException;
public class TestJPAFacadeHelper extends SingleEMFTestCase { public class TestJPAFacadeHelper extends SingleEMFTestCase {
MetaDataRepository repo = null; MetaDataRepository repo = null;
public void setUp() { 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, 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(); repo = emf.getConfiguration().getMetaDataRepositoryInstance();
} }
@ -63,10 +86,27 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase {
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // expected
} }
// Initialize and persist entity
EmbeddedIdClass id = new EmbeddedIdClass(); 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 { public void testCompositeId() throws Exception {
@ -76,10 +116,25 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase {
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // expected
} }
CompositeId id = new CompositeId(12, "name"); int intId = 1;
assertEquals(ObjectId.class, JPAFacadeHelper.toOpenJPAObjectId(cmd, id).getClass()); 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 { public void testBasic() throws Exception {
@ -95,13 +150,235 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase {
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // 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)); 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 { public void testDerivedId() throws Exception {
ClassMetaData cmd = repo.getMetaData(EDSQLDateID.class, null, true); ClassMetaData cmd = repo.getMetaData(EDSQLDateID.class, null, true);
try { try {
@ -109,16 +386,94 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase {
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // 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 { public void testNoId() throws Exception {
ClassMetaData cmd = repo.getMetaData(AllFieldTypes.class, null, true); ClassMetaData cmd = repo.getMetaData(AllFieldTypes.class, null, true);
try { 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<Object> oids) method sig. // ...(ClassMetaData meta, Collection<Object> oids) method sig.
Collection ids = new ArrayList<AllFieldTypes>(); Collection ids = new ArrayList<AllFieldTypes>();
ids.add(new AllFieldTypes()); ids.add(new AllFieldTypes());
@ -126,14 +481,12 @@ public class TestJPAFacadeHelper extends SingleEMFTestCase {
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // expected
} }
try { try {
JPAFacadeHelper.toOpenJPAObjectId(cmd, "a"); JPAFacadeHelper.toOpenJPAObjectId(cmd, "a");
fail("Didn't fail!"); fail("Didn't fail!");
} catch (UserException re) { } catch (UserException re) {
// expected // expected
} }
OpenJPAEntityManagerSPI em = emf.createEntityManager(); OpenJPAEntityManagerSPI em = emf.createEntityManager();
em.getTransaction().begin(); em.getTransaction().begin();

View File

@ -18,6 +18,7 @@
*/ */
package org.apache.openjpa.persistence; package org.apache.openjpa.persistence;
import java.lang.reflect.Modifier;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
@ -26,23 +27,28 @@ import java.util.Collection;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.enhance.PCRegistry;
import org.apache.openjpa.kernel.Broker; import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.kernel.BrokerFactory; import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.kernel.BrokerImpl.StateManagerId;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.ValueMetaData; import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.util.ApplicationIds;
import org.apache.openjpa.util.BigDecimalId; import org.apache.openjpa.util.BigDecimalId;
import org.apache.openjpa.util.BigIntegerId; import org.apache.openjpa.util.BigIntegerId;
import org.apache.openjpa.util.ByteId; import org.apache.openjpa.util.ByteId;
import org.apache.openjpa.util.CharId; import org.apache.openjpa.util.CharId;
import org.apache.openjpa.util.DoubleId; import org.apache.openjpa.util.DoubleId;
import org.apache.openjpa.util.FloatId; import org.apache.openjpa.util.FloatId;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.Id; import org.apache.openjpa.util.Id;
import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.IntId; import org.apache.openjpa.util.IntId;
import org.apache.openjpa.util.LongId; import org.apache.openjpa.util.LongId;
import org.apache.openjpa.util.ObjectId; import org.apache.openjpa.util.ObjectId;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OpenJPAId; import org.apache.openjpa.util.OpenJPAId;
import org.apache.openjpa.util.ShortId; import org.apache.openjpa.util.ShortId;
import org.apache.openjpa.util.StringId; import org.apache.openjpa.util.StringId;
@ -221,64 +227,62 @@ public class JPAFacadeHelper {
if (oid instanceof OpenJPAId) { if (oid instanceof OpenJPAId) {
return oid; return oid;
} }
Class<?> cls = meta.getDescribedType(); Class<?> cls = meta.getDescribedType();
Class<?> oidType = meta.getObjectIdType();
FieldMetaData[] pks = meta.getPrimaryKeyFields(); FieldMetaData[] pks = meta.getPrimaryKeyFields();
Object expected = oidType; Object expected = meta.getObjectIdType();
Object actual = oid.getClass(); try {
switch (meta.getIdentityType()) {
// embedded id and derived id case ClassMetaData.ID_DATASTORE:
if (pks.length > 0 && (pks[0].isEmbedded() || pks[0].isTypePC())) { if (oid instanceof String && ((String) oid).startsWith(StateManagerId.STRING_PREFIX))
if (pks[0].getDeclaredType().equals(oid.getClass())) { return new StateManagerId((String) oid);
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 {
return new Id(cls, ((Number) oid).longValue()); return new Id(cls, ((Number) oid).longValue());
} catch (ClassCastException cce) { case ClassMetaData.ID_APPLICATION:
// swallow, the proper exception will be thrown below if (ImplHelper.isAssignable(meta.getObjectIdType(), oid.getClass())) {
expected = Number.class; 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 }));
} }
/** /**