You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/02/27 00:35:55 UTC

svn commit: r748349 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-kernel/src/main/java/org/apache/openjpa/meta/ openjpa-kernel/src/main/java/org/apache/openjpa/util/ openjpa-persistence-jdbc/src/test/java/org/apa...

Author: faywang
Date: Thu Feb 26 23:35:54 2009
New Revision: 748349

URL: http://svn.apache.org/viewvc?rev=748349&view=rev
Log:
OPENJPA-931: IdClass support

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory3.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory4.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person3.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person4.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId3.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId4.java
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory2.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person2.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Thu Feb 26 23:35:54 2009
@@ -656,8 +656,10 @@
                 //The name of the attribute within the composite key to which 
                 //the relationship attribute corresponds.
                 Object target = ((ObjectId)sm.getObjectId()).getId();
+                if (target == null)
+                    return;
                 setMappedByIdValue(target, pkVal, mappedByIdFieldName);
-                    pkVal = target;
+                pkVal = target;
             }
             sm.storeObjectField(fmds[0].getIndex(), pkVal);
         }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Thu Feb 26 23:35:54 2009
@@ -194,6 +194,7 @@
     private FetchGroup[] _fgs = null;
     private FetchGroup[] _customFGs = null;
     private boolean _intercepting = false;
+    private Boolean _useIdClassFromParent = null;
 
     /**
      * Constructor. Supply described type and repository.
@@ -439,8 +440,17 @@
      * The metadata-specified class to use for the object ID.
      */
     public Class getObjectIdType() {
-        if (_objectId != null)
-            return _objectId;
+        // if this entity does not use IdClass from the parent entity,
+        // just return the _objectId set during annotation parsing time.
+        if (!useIdClassFromParent()) {
+            if (_objectId != null)
+                return _objectId;
+        } 
+        
+        // if this entity uses IdClass from the parent entity,
+        // the _objectId set during the parsing time should be
+        // ignored, and let Openjpa determine the objectId type
+        // of this entity.
         if (getIdentityType() != ID_APPLICATION)
             return null;
         ClassMetaData sup = getPCSuperclassMetaData();
@@ -504,6 +514,13 @@
 
     /**
      * The metadata-specified class to use for the object ID.
+     * When there is IdClass annotation, AnnotationMetaDataParser
+     * will call this method to set ObjectId type. However, if 
+     * this is a derived identity in the child entity where a 
+     * relation field (parent entity) is used as an id, and this 
+     * relation field has an IdClass, the IdClass annotation in 
+     * the child entity can be ignored as Openjpa will automatically   
+     * wrap parent's IdClass as child's IdClass. 
      */
     public void setObjectIdType(Class cls, boolean shared) {
         _objectId = null;
@@ -1904,6 +1921,45 @@
             validateAppIdClassPKs(this, pks, _objectId);
         }
     }
+    /**
+     * Return true if this class uses IdClass derived from idClass of the 
+     * parent entity which annotated as id in the child class. 
+     * In this case, there are no key fields in the child entity corresponding 
+     * to the fields in the IdClass.
+     */
+    public boolean useIdClassFromParent() {
+        if (_useIdClassFromParent == null) {
+            if (_objectId == null)
+                _useIdClassFromParent = false;
+            else {
+                FieldMetaData[] pks = getPrimaryKeyFields();
+                if (pks.length != 1) 
+                    _useIdClassFromParent = false;
+                else {
+                    ClassMetaData pkMeta = pks[0].getTypeMetaData();
+                    if (pkMeta == null)
+                        _useIdClassFromParent = false;
+                    else {
+                        Class pkType = pkMeta.getObjectIdType();
+                        if (pkType == ObjectId.class) //parent id is EmbeddedId
+                            pkType = pkMeta.getPrimaryKeyFields()[0].getType();
+                        if (pkType == _objectId)
+                            _useIdClassFromParent = true;
+                        else {
+                            Field f = Reflection.findField(_objectId, 
+                                pks[0].getName(), false);
+                            if (f != null) 
+                                _useIdClassFromParent = false;
+                            else 
+                                throw new MetaDataException(_loc.get("invalid-id",
+                                    _type, pks[0].getName()));
+                        }
+                    }
+                }
+            }
+        }
+        return _useIdClassFromParent.booleanValue();
+    }
 
     /**
      * Return true if this class has a concrete persistent superclass.

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java Thu Feb 26 23:35:54 2009
@@ -504,6 +504,8 @@
             key = ((ObjectId)id).getId();
         Object val = null;
         if (mappedByIdFieldName.length() != 0) {
+            if (((ObjectId)id).getId() == null)
+                return false;        	
             Class idClass = ((ObjectId)id).getId().getClass();
             val = Reflection.get(key, 
                     Reflection.findField(idClass, mappedByIdFieldName, true)); 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory2.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory2.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory2.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory2.java Thu Feb 26 23:35:54 2009
@@ -21,6 +21,7 @@
 import javax.persistence.*;
 
 @Entity
+@Table(name="MED2_MBI")
 public class MedicalHistory2 {
     @Id
     long id;

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory3.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory3.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory3.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory3.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="MED3_MBI")
+@IdClass(PersonId3.class)
+public class MedicalHistory3 {
+    String name;
+    
+    @Id
+    @OneToOne Person3 patient;
+    
+    public Person3 getPatient() {
+        return patient;
+    }
+    
+    public void setPatient(Person3 p) {
+        this.patient = p;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof MedicalHistory3)) return false;
+        MedicalHistory3 m0 = (MedicalHistory3)o;
+        String name0 = m0.getName();
+        if (name != null && !name.equals(name0)) return false;
+        if (name == null && name0 != null) return false;
+        Person3 p0 = m0.getPatient();
+        if (patient != null && !patient.equals(p0)) return false;
+        if (patient == null && p0 != null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        ret = ret * 31 + name.hashCode();
+       	//ret = ret * 31 + patient.hashCode();
+        return ret;
+    }
+    
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory4.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory4.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory4.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory4.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="MED4_MBI")
+@IdClass(PersonId4.class)
+public class MedicalHistory4 {
+    String name;
+    
+    @Id
+    @OneToOne Person4 patient;
+    
+    public Person4 getPatient() {
+        return patient;
+    }
+    
+    public void setPatient(Person4 p) {
+        this.patient = p;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof MedicalHistory4)) return false;
+        MedicalHistory4 m0 = (MedicalHistory4)o;
+        String name0 = m0.getName();
+        if (name != null && !name.equals(name0)) return false;
+        if (name == null && name0 != null) return false;
+        Person4 p0 = m0.getPatient();
+        if (patient != null && !patient.equals(p0)) return false;
+        if (patient == null && p0 != null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        ret = ret * 31 + name.hashCode();
+        ret = ret * 31 + patient.id.firstName.hashCode();
+        ret = ret * 31 + patient.id.lastName.hashCode();
+        return ret;
+    }
+    
+}

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person2.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person2.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person2.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person2.java Thu Feb 26 23:35:54 2009
@@ -21,6 +21,7 @@
 import javax.persistence.*;
 
 @Entity
+@Table(name="PER2_MBI")
 public class Person2 {
     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person3.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person3.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person3.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person3.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="PER3_MBI")
+@IdClass(PersonId3.class)
+public class Person3 {
+    @Id
+    String firstName;
+    
+    @Id
+    String lastName;
+        
+    @OneToOne(mappedBy="patient")
+    MedicalHistory3 medical;
+    
+    public String getFirstName() {
+        return firstName;
+    }
+    
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+    
+    public String getLastName() {
+        return lastName;
+    }
+    
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+    
+    public MedicalHistory3 getMedical() {
+        return medical;
+    }
+    
+    public void setMedical(MedicalHistory3 medical) {
+        this.medical = medical;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof Person3)) return false;
+        Person3 p0 = (Person3)o;
+        String firstName0 = p0.getFirstName();
+        String lastName0 = p0.getLastName();
+        MedicalHistory3 medical0 = p0.getMedical();
+        if (!firstName.equals(firstName0)) return false;
+        if (!lastName.equals(lastName0)) return false;
+        if (medical != null && medical0 != null && !medical.name.equals(medical0.name)) return false; 
+        if (medical == null && medical0 != null) return false;
+        if (medical != null && medical0 == null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        ret = ret * 31 + firstName.hashCode();
+        ret = ret * 31 + lastName.hashCode();
+        if (medical != null)
+        	ret = ret * 31 + medical.hashCode();
+        return ret;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person4.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person4.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person4.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person4.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="PER4_MBI")
+public class Person4 {
+    @EmbeddedId
+    PersonId4 id;
+    
+    @OneToOne(mappedBy="patient")
+    MedicalHistory4 medical;
+    
+    public PersonId4 getId() {
+        return id;
+    }
+    
+    public void setId(PersonId4 id) {
+        this.id = id;
+    }
+    
+    public MedicalHistory4 getMedical() {
+        return medical;
+    }
+    
+    public void setMedical(MedicalHistory4 medical) {
+        this.medical = medical;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof Person4)) return false;
+        Person4 p0 = (Person4)o;
+        PersonId4 id0 = p0.getId();
+        if (!id.equals(id0)) return false;
+        MedicalHistory4 medical0 = p0.getMedical();
+        if (medical != null && 
+            !medical.patient.getId().equals(medical0.patient.getId())) return false; 
+        if (medical == null && medical0 != null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        ret = ret * 31 + id.hashCode();
+        if (medical != null)
+        	ret = ret * 31 + medical.hashCode();
+        return ret;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId3.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId3.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId3.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId3.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+public class PersonId3 {
+    String firstName;
+    String lastName;
+    
+    public PersonId3() {}
+    
+    public PersonId3(String firstName, String lastName) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+    }
+    
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+    
+    public String getFirstName() {
+        return firstName;
+    }
+    
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+    
+    public String getLastName() {
+        return lastName;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof PersonId3)) return false;
+        PersonId3 eid = (PersonId3)o;
+        String firstName0 = eid.getFirstName();
+        String lastName0 = eid.getLastName();
+        if (firstName != null && !firstName.equals(firstName0)) return false;
+        if (firstName == null && firstName0 != null) return false;
+        if (lastName != null && !lastName.equals(lastName0)) return false;
+        if (lastName == null && lastName0 != null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        if (firstName != null)
+        	ret = ret * 31 + firstName.hashCode();
+        if (lastName != null)
+        ret = ret * 31 + lastName.hashCode();
+        return ret;
+    }
+    
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId4.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId4.java?rev=748349&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId4.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId4.java Thu Feb 26 23:35:54 2009
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.enhance.identity;
+
+import javax.persistence.*;
+
+@Embeddable
+public class PersonId4 {
+    String firstName;
+    String lastName;
+    
+    public PersonId4() {}
+    
+    public PersonId4(String firstName, String lastName) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+    }
+    
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+    
+    public String getFirstName() {
+        return firstName;
+    }
+    
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+    
+    public String getLastName() {
+        return lastName;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == null) return false;
+        if (!(o instanceof PersonId4)) return false;
+        PersonId4 eid = (PersonId4)o;
+        String firstName0 = eid.getFirstName();
+        String lastName0 = eid.getLastName();
+        if (firstName != null && !firstName.equals(firstName0)) return false;
+        if (firstName == null && firstName0 != null) return false;
+        if (lastName != null && !lastName.equals(lastName0)) return false;
+        if (lastName == null && lastName0 != null) return false;
+        return true;
+    }
+    
+    public int hashCode() {
+        int ret = 0;
+        if (firstName != null)
+            ret = ret * 31 + firstName.hashCode();
+        if (lastName != null)
+            ret = ret * 31 + lastName.hashCode();
+        return ret;
+    }
+    
+}

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java?rev=748349&r1=748348&r2=748349&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java Thu Feb 26 23:35:54 2009
@@ -49,6 +49,11 @@
     public Map<String, Person2> persons2 = new HashMap<String, Person2>();
     public Map<String, MedicalHistory2> medicals2 = 
         new HashMap<String, MedicalHistory2>();
+    public Map<String, Person3> persons3 = new HashMap<String, Person3>();
+    public Map<String, MedicalHistory3> medicals3 = new HashMap<String, 
+        MedicalHistory3>();
+    public Map<String, Person4> persons4 = new HashMap<String, Person4>();
+    public Map<String, MedicalHistory4> medicals4 = new HashMap<String, MedicalHistory4>();
 
     public Map<Integer, Employee3> emps3 = new HashMap<Integer, Employee3>();
     public Map<Object, Dependent3> depMap3 = 
@@ -66,14 +71,20 @@
     public int mId1 = 1;
     public int pId2 = 1;
     public int mId2 = 1;
+    public int pId3 = 1;
+    public int mId3 = 1;
+    public int pId4 = 1;
+    public int mId4 = 1;
 
     public void setUp() throws Exception {
         super.setUp(DROP_TABLES, Dependent1.class, Employee1.class, 
             DependentId1.class, Dependent2.class, Employee2.class,
             DependentId2.class, EmployeeId2.class, MedicalHistory1.class,
             Person1.class, PersonId1.class, MedicalHistory2.class,
-            Person2.class, Dependent3.class, Employee3.class, 
-            DependentId3.class, Parent3.class);
+            Person2.class, Person3.class, MedicalHistory3.class, 
+            Person4.class, PersonId4.class, MedicalHistory4.class,
+            Dependent3.class, Employee3.class, DependentId3.class, 
+            Parent3.class);
     }
 
     /**
@@ -122,6 +133,24 @@
         queryObj5();
     }
 
+    /**
+     * This is spec 2.4.1.2 Example 5, case(a)
+     */
+    public void testMappedById6() {
+        createObj6();
+        findObj6();
+        queryObj6();
+    }
+
+    /**
+     * This is spec 2.4.1.2 Example 6, case(a)
+     */
+    public void testMappedById7() {
+        createObj7();
+        findObj7();
+        queryObj7();
+    }
+
     public void createObj1() {
         EntityManager em = emf.createEntityManager();
         EntityTransaction tran = em.getTransaction();
@@ -377,7 +406,7 @@
         EntityManager em = emf.createEntityManager();
         Person2 p = em.find(Person2.class, ssn);
         Person2 p1 = p.getMedical().getPatient();
-        Assert.assertEquals(p1, p);
+        assertEquals(p1, p);
     }
 
     public void queryObj4() {
@@ -418,9 +447,8 @@
         String name = m.getName();
         MedicalHistory2 m0 = medicals2.get(name);
         MedicalHistory2 m1 = m.getPatient().getMedical();
-        Assert.assertEquals(m1, m);
+        assertEquals(m1, m);
     }
-
     
     public void createObj5() {
         EntityManager em = emf.createEntityManager();
@@ -436,7 +464,6 @@
         	depMap3.put(did.getId(), d);
         }
         
-        
         em.close();
     }
 
@@ -497,4 +524,121 @@
         assertEquals(d0, d);
     }
     
+    public void createObj6() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        for (int i = 0; i < numPersons; i++)
+            createPerson3(em, pId3++);
+        tran.begin();
+        em.flush();
+        tran.commit();
+        em.close();
+    }
+
+    public Person3 createPerson3(EntityManager em, int id) {
+        Person3 p = new Person3();
+        p.setFirstName("f_" + id);
+        p.setLastName("l_" + id);
+        MedicalHistory3 m = createMedicalHistory3(em, mId3++);
+        m.setPatient(p);
+        p.setMedical(m);
+        em.persist(m);
+        em.persist(p);
+        persons3.put(p.getFirstName(), p);
+        medicals3.put(m.getPatient().getFirstName(), m);
+        return p;
+    }
+
+    public MedicalHistory3 createMedicalHistory3(EntityManager em, int id) {
+        MedicalHistory3 m = new MedicalHistory3();
+        m.setName("medical_" + id);
+        return m;
+    }
+
+    public void findObj6() {
+        EntityManager em = emf.createEntityManager();
+        Person3 p = em.find(Person3.class, new PersonId3("f_1", "l_1"));
+        Person3 p0 = persons3.get("f_1");
+        Person3 p1 = p.getMedical().getPatient();
+        assertEquals(p, p1);
+    }
+
+    public void queryObj6() { 
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        tran.begin();
+        String firstName = "f_1";
+        String jpql = "select m from MedicalHistory3 m where m.patient.firstName = '" + firstName + "'";
+        Query q = em.createQuery(jpql);
+        List<MedicalHistory3> ms = q.getResultList();
+        for (MedicalHistory3 m : ms) {
+            assertMedicalHistory3(m, firstName);
+        }
+        tran.commit();
+        em.close();
+    }
+
+    public void assertMedicalHistory3(MedicalHistory3 m, String firstName) {
+        MedicalHistory3 m0 = medicals3.get(firstName);
+        assertEquals(m0, m);
+    }
+    
+    public void createObj7() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        for (int i = 0; i < numPersons; i++)
+            createPerson4(em, pId4++);
+        tran.begin();
+        em.flush();
+        tran.commit();
+        em.close();
+    }
+
+    public Person4 createPerson4(EntityManager em, int id) {
+        Person4 p = new Person4();
+        p.setId(new PersonId4("f_" + id, "l_" + id));
+        MedicalHistory4 m = createMedicalHistory4(em, mId4++);
+        m.setPatient(p);
+        p.setMedical(m);
+        em.persist(p);
+        em.persist(m);
+        persons4.put(p.getId().getFirstName(), p);
+        medicals4.put(m.getPatient().getId().getFirstName(), m);
+        return p;
+    }
+
+    public MedicalHistory4 createMedicalHistory4(EntityManager em, int id) {
+        MedicalHistory4 m = new MedicalHistory4();
+        m.setName("medical_" + id);
+        return m;
+    }
+
+    public void findObj7() {
+        EntityManager em = emf.createEntityManager();
+        Person4 p = em.find(Person4.class, new PersonId4("f_1", "l_1"));
+        Person4 p0 = persons4.get("f_1");
+        Person4 p1 = p.getMedical().getPatient();
+        assertEquals(p1, p);
+    }
+
+    public void queryObj7() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        tran.begin();
+        String firstName = "f_1";
+        String jpql = "select m from MedicalHistory4 m where m.patient.id.firstName = '" + firstName + "'";
+        Query q = em.createQuery(jpql);
+        List<MedicalHistory4> ms = q.getResultList();
+        for (MedicalHistory4 m : ms) {
+            assertMedicalHistory4(m, firstName);
+        }
+        tran.commit();
+        em.close();
+    }
+
+    public void assertMedicalHistory4(MedicalHistory4 m, String firstName) {
+        MedicalHistory4 m0 = medicals4.get(firstName);
+        MedicalHistory4 m1 = m.getPatient().getMedical();
+        assertEquals(m1, m);
+    }
 }