OPENJPA-214 : Support float and double fields as single-field identity primary

keys.



git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@527648 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2007-04-11 20:25:11 +00:00
parent b4a3a77840
commit 3885031a89
9 changed files with 375 additions and 1 deletions

View File

@ -62,8 +62,10 @@ import org.apache.openjpa.util.InternalException;
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.DateId; import org.apache.openjpa.util.DateId;
import org.apache.openjpa.util.DoubleId;
import org.apache.openjpa.util.Id; import org.apache.openjpa.util.Id;
import org.apache.openjpa.util.IntId; import org.apache.openjpa.util.IntId;
import org.apache.openjpa.util.FloatId;
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.ShortId; import org.apache.openjpa.util.ShortId;
@ -1632,6 +1634,32 @@ public class PCEnhancer {
code.invokespecial().setMethod(Character.class, code.invokespecial().setMethod(Character.class,
"<init>", void.class, new Class[] {char.class}); "<init>", void.class, new Class[] {char.class});
break; 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, "<init>",
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, "<init>",
void.class, new Class[]{float.class});
break;
case JavaTypes.INT_OBJ: case JavaTypes.INT_OBJ:
code.anew().setType(Integer.class); code.anew().setType(Integer.class);
code.dup(); code.dup();
@ -1927,6 +1955,10 @@ public class PCEnhancer {
return byte.class; return byte.class;
case JavaTypes.CHAR_OBJ: case JavaTypes.CHAR_OBJ:
return char.class; return char.class;
case JavaTypes.DOUBLE_OBJ:
return double.class;
case JavaTypes.FLOAT_OBJ:
return float.class;
case JavaTypes.INT_OBJ: case JavaTypes.INT_OBJ:
return int.class; return int.class;
case JavaTypes.SHORT_OBJ: case JavaTypes.SHORT_OBJ:

View File

@ -44,6 +44,8 @@ import org.apache.openjpa.lib.xml.Commentable;
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.DateId; 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.GeneralException;
import org.apache.openjpa.util.IntId; import org.apache.openjpa.util.IntId;
import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.InternalException;
@ -438,6 +440,14 @@ public class ClassMetaData
case JavaTypes.CHAR_OBJ: case JavaTypes.CHAR_OBJ:
_objectId = CharId.class; _objectId = CharId.class;
break; 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:
case JavaTypes.INT_OBJ: case JavaTypes.INT_OBJ:
_objectId = IntId.class; _objectId = IntId.class;

View File

@ -125,6 +125,18 @@ public class ApplicationIds {
case JavaTypes.CHAR_OBJ: case JavaTypes.CHAR_OBJ:
return new CharId(meta.getDescribedType(), return new CharId(meta.getDescribedType(),
((Character) val).charValue()); ((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:
case JavaTypes.INT_OBJ: case JavaTypes.INT_OBJ:
if (!convert && !(val instanceof Integer)) if (!convert && !(val instanceof Integer))
@ -217,6 +229,14 @@ public class ApplicationIds {
case JavaTypes.CHAR_OBJ: case JavaTypes.CHAR_OBJ:
return new CharId(cls, ((CharId) oid).getId(), return new CharId(cls, ((CharId) oid).getId(),
koid.hasSubclasses()); 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:
case JavaTypes.INT_OBJ: case JavaTypes.INT_OBJ:
return new IntId(cls, ((IntId) oid).getId(), return new IntId(cls, ((IntId) oid).getId(),

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -35,7 +35,18 @@ import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.lib.conf.ConfigurationProvider; import org.apache.openjpa.lib.conf.ConfigurationProvider;
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.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 * Static helper method for JPA users, including switching
@ -373,6 +384,10 @@ public class OpenJPAPersistence
return new ByteId(cls, (Byte) oid); return new ByteId(cls, (Byte) oid);
if (oid instanceof Character) if (oid instanceof Character)
return new CharId(cls, (Character) oid); 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) if (oid instanceof Integer)
return new IntId(cls, (Integer) oid); return new IntId(cls, (Integer) oid);
if (oid instanceof Long) if (oid instanceof Long)
@ -440,6 +455,10 @@ public class OpenJPAPersistence
return Byte.class; return Byte.class;
if (oidClass == CharId.class) if (oidClass == CharId.class)
return Character.class; return Character.class;
if (oidClass == DoubleId.class)
return Double.class;
if (oidClass == FloatId.class)
return Float.class;
if (oidClass == IntId.class) if (oidClass == IntId.class)
return Integer.class; return Integer.class;
if (oidClass == LongId.class) if (oidClass == LongId.class)