diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java index da30e90ee..76e8427b0 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java @@ -62,8 +62,10 @@ 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.DoubleId; import org.apache.openjpa.util.Id; import org.apache.openjpa.util.IntId; +import org.apache.openjpa.util.FloatId; import org.apache.openjpa.util.LongId; import org.apache.openjpa.util.ObjectId; import org.apache.openjpa.util.ShortId; @@ -1632,6 +1634,32 @@ public class PCEnhancer { code.invokespecial().setMethod(Character.class, "", void.class, new Class[] {char.class}); break; + case JavaTypes.DOUBLE_OBJ: + code.anew().setType(Double.class); + code.dup(); + // no break + case JavaTypes.DOUBLE: + code.aload().setLocal(oid); + code.checkcast().setType(DoubleId.class); + code.invokevirtual().setMethod(DoubleId.class, "getId", + double.class, null); + if (pkcode == JavaTypes.DOUBLE_OBJ) + code.invokespecial().setMethod(Double.class, "", + void.class, new Class[]{double.class}); + break; + case JavaTypes.FLOAT_OBJ: + code.anew().setType(Float.class); + code.dup(); + // no break + case JavaTypes.FLOAT: + code.aload().setLocal(oid); + code.checkcast().setType(FloatId.class); + code.invokevirtual().setMethod(FloatId.class, "getId", + float.class, null); + if (pkcode == JavaTypes.FLOAT_OBJ) + code.invokespecial().setMethod(Float.class, "", + void.class, new Class[]{float.class}); + break; case JavaTypes.INT_OBJ: code.anew().setType(Integer.class); code.dup(); @@ -1927,6 +1955,10 @@ public class PCEnhancer { return byte.class; case JavaTypes.CHAR_OBJ: return char.class; + case JavaTypes.DOUBLE_OBJ: + return double.class; + case JavaTypes.FLOAT_OBJ: + return float.class; case JavaTypes.INT_OBJ: return int.class; case JavaTypes.SHORT_OBJ: 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 600d1ee2e..939ee57a6 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 @@ -44,6 +44,8 @@ import org.apache.openjpa.lib.xml.Commentable; import org.apache.openjpa.util.ByteId; import org.apache.openjpa.util.CharId; import org.apache.openjpa.util.DateId; +import org.apache.openjpa.util.DoubleId; +import org.apache.openjpa.util.FloatId; import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.IntId; import org.apache.openjpa.util.InternalException; @@ -438,6 +440,14 @@ public class ClassMetaData case JavaTypes.CHAR_OBJ: _objectId = CharId.class; break; + case JavaTypes.DOUBLE: + case JavaTypes.DOUBLE_OBJ: + _objectId = DoubleId.class; + break; + case JavaTypes.FLOAT: + case JavaTypes.FLOAT_OBJ: + _objectId = FloatId.class; + break; case JavaTypes.INT: case JavaTypes.INT_OBJ: _objectId = IntId.class; diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java index 7716a870f..b7cab3c7d 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java @@ -125,6 +125,18 @@ public class ApplicationIds { case JavaTypes.CHAR_OBJ: return new CharId(meta.getDescribedType(), ((Character) val).charValue()); + case JavaTypes.DOUBLE: + case JavaTypes.DOUBLE_OBJ: + if (!convert && !(val instanceof Double)) + throw new ClassCastException("!(x instanceof Double)"); + return new DoubleId(meta.getDescribedType(), + ((Number) val).doubleValue()); + case JavaTypes.FLOAT: + case JavaTypes.FLOAT_OBJ: + if (!convert && !(val instanceof Float)) + throw new ClassCastException("!(x instanceof Float)"); + return new FloatId(meta.getDescribedType(), + ((Number) val).floatValue()); case JavaTypes.INT: case JavaTypes.INT_OBJ: if (!convert && !(val instanceof Integer)) @@ -217,6 +229,14 @@ public class ApplicationIds { case JavaTypes.CHAR_OBJ: return new CharId(cls, ((CharId) oid).getId(), koid.hasSubclasses()); + case JavaTypes.DOUBLE: + case JavaTypes.DOUBLE_OBJ: + return new DoubleId(cls, ((DoubleId) oid).getId(), + koid.hasSubclasses()); + case JavaTypes.FLOAT: + case JavaTypes.FLOAT_OBJ: + return new FloatId(cls, ((FloatId) oid).getId(), + koid.hasSubclasses()); case JavaTypes.INT: case JavaTypes.INT_OBJ: return new IntId(cls, ((IntId) oid).getId(), diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/DoubleId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/DoubleId.java new file mode 100644 index 000000000..cbd4241a7 --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/DoubleId.java @@ -0,0 +1,66 @@ +/* + * 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.util; + +/** + * {@link OpenJPAId} subclass appropriate for double fields. + * + * @author Abe White + */ +public final class DoubleId + extends OpenJPAId { + + private final double key; + + public DoubleId(Class cls, Double key) { + this(cls, (key == null) ? 0D : key.doubleValue()); + } + + public DoubleId(Class cls, String key) { + this(cls, (key == null) ? 0D : Double.parseDouble(key)); + } + + public DoubleId(Class cls, double key) { + super(cls); + this.key = key; + } + + public DoubleId(Class cls, double key, boolean subs) { + super(cls, subs); + this.key = key; + } + + public double getId() { + return key; + } + + public Object getIdObject() { + return new Double(key); + } + + public String toString() { + return Double.toString(key); + } + + protected int idHash() { + return (int) (Double.doubleToLongBits(key) + ^ (Double.doubleToLongBits(key) >>> 32)); + } + + protected boolean idEquals(OpenJPAId o) { + return key == ((DoubleId) o).key; + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/FloatId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/FloatId.java new file mode 100644 index 000000000..95ae0236d --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/FloatId.java @@ -0,0 +1,65 @@ +/* + * 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.util; + +/** + * {@link OpenJPAId} subclass appropriate for float fields. + * + * @author Abe White + */ +public final class FloatId + extends OpenJPAId { + + private final float key; + + public FloatId(Class cls, Float key) { + this(cls, (key == null) ? 0F : key.floatValue()); + } + + public FloatId(Class cls, String key) { + this(cls, (key == null) ? 0F : Float.parseFloat(key)); + } + + public FloatId(Class cls, float key) { + super(cls); + this.key = key; + } + + public FloatId(Class cls, float key, boolean subs) { + super(cls, subs); + this.key = key; + } + + public float getId() { + return key; + } + + public Object getIdObject() { + return new Float(key); + } + + public String toString() { + return Float.toString(key); + } + + protected int idHash() { + return Float.floatToIntBits(key); + } + + protected boolean idEquals(OpenJPAId o) { + return key == ((FloatId) o).key; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/DoubleObjIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/DoubleObjIdEntity.java new file mode 100644 index 000000000..4fc872f1b --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/DoubleObjIdEntity.java @@ -0,0 +1,43 @@ +/* + * 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.identity; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class DoubleObjIdEntity { + + @Id + private Double id; + private int data; + + public Double getId() { + return id; + } + + public void setId(Double id) { + this.id = id; + } + + public int getData() { + return data; + } + + public void setData(int data) { + this.data = data; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/FloatIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/FloatIdEntity.java new file mode 100644 index 000000000..c03c823bb --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/FloatIdEntity.java @@ -0,0 +1,43 @@ +/* + * 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.identity; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class FloatIdEntity { + + @Id + private float id; + private int data; + + public float getId() { + return id; + } + + public void setId(float id) { + this.id = id; + } + + public int getData() { + return data; + } + + public void setData(int data) { + this.data = data; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestFloatingPointIds.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestFloatingPointIds.java new file mode 100644 index 000000000..3220a7d89 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestFloatingPointIds.java @@ -0,0 +1,76 @@ +/* + * 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.identity; + +import java.sql.Date; +import javax.persistence.EntityManager; + +import junit.textui.TestRunner; +import org.apache.openjpa.persistence.test.SingleEMFTestCase; + +/** + * Test that entities can use floating point ids. + * + * @author Abe White + */ +public class TestFloatingPointIds + extends SingleEMFTestCase { + + public void setUp() { + setUp(FloatIdEntity.class, DoubleObjIdEntity.class); + } + + public void testPersistFloat() { + FloatIdEntity e = new FloatIdEntity(); + e.setId(3F); + e.setData(33); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(e); + em.getTransaction().commit(); + assertEquals(3F, e.getId()); + em.close(); + + em = emf.createEntityManager(); + e = em.find(FloatIdEntity.class, 3F); + assertEquals(33, e.getData()); + em.close(); + } + + public void testPersistDoubleObj() { + DoubleObjIdEntity e = new DoubleObjIdEntity(); + e.setId(new Double(4D)); + e.setData(44); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(e); + em.getTransaction().commit(); + assertEquals(new Double(4D), e.getId()); + em.close(); + + em = emf.createEntityManager(); + e = em.find(DoubleObjIdEntity.class, new Double(4D)); + assertEquals(44, e.getData()); + em.close(); + } + + public static void main(String[] args) { + TestRunner.run(TestFloatingPointIds.class); + } +} + diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAPersistence.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAPersistence.java index ccf29bfe7..8bfe09e89 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAPersistence.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAPersistence.java @@ -35,7 +35,18 @@ import org.apache.openjpa.kernel.BrokerFactory; import org.apache.openjpa.lib.conf.ConfigurationProvider; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.meta.ClassMetaData; -import org.apache.openjpa.util.*; +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.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.OpenJPAId; +import org.apache.openjpa.util.ShortId; +import org.apache.openjpa.util.StringId; /** * Static helper method for JPA users, including switching @@ -373,6 +384,10 @@ public class OpenJPAPersistence return new ByteId(cls, (Byte) oid); if (oid instanceof Character) return new CharId(cls, (Character) oid); + if (oid instanceof Double) + return new DoubleId(cls, (Double) oid); + if (oid instanceof Float) + return new FloatId(cls, (Float) oid); if (oid instanceof Integer) return new IntId(cls, (Integer) oid); if (oid instanceof Long) @@ -440,6 +455,10 @@ public class OpenJPAPersistence return Byte.class; if (oidClass == CharId.class) return Character.class; + if (oidClass == DoubleId.class) + return Double.class; + if (oidClass == FloatId.class) + return Float.class; if (oidClass == IntId.class) return Integer.class; if (oidClass == LongId.class)