diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java index 81767ee87..e6b7035b6 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java @@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta; import java.sql.SQLException; +import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.strats.NoneFieldStrategy; @@ -38,12 +39,15 @@ import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.jdbc.sql.SelectExecutor; import org.apache.openjpa.kernel.FetchConfiguration; import org.apache.openjpa.kernel.OpenJPAStateManager; +import org.apache.openjpa.kernel.StateManagerImpl; import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.JavaTypes; +import org.apache.openjpa.util.ApplicationIds; import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.MetaDataException; +import org.apache.openjpa.util.ObjectId; /** * Specialization of metadata for relational databases. @@ -587,6 +591,19 @@ public class FieldMapping public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm) throws SQLException { + if (sm instanceof StateManagerImpl) { + int mappedByIdValueFrom = ((StateManagerImpl)sm).getMappedByIdValueFrom(); + if (isPrimaryKey() && mappedByIdValueFrom != -1) { + PersistenceCapable pc = (PersistenceCapable)sm.fetchObject(mappedByIdValueFrom); + StateManagerImpl pkSm = (StateManagerImpl)pc.pcGetStateManager(); + ObjectId fromId = (ObjectId)pkSm.getId(); + sm.storeObject(getIndex(), fromId.getId()); + ObjectId toId = (ObjectId)sm.getId(); + ApplicationIds.setKey(fromId, toId); + ObjectId toObjectId = (ObjectId)sm.getObjectId(); + ApplicationIds.setKey(fromId, toObjectId); + } + } assertStrategy().insert(sm, store, rm); } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java index 808c9066a..4e3ddd4ef 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java @@ -25,13 +25,17 @@ import java.util.List; import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.Embeddable; import org.apache.openjpa.jdbc.meta.FieldMapping; import org.apache.openjpa.jdbc.meta.FieldStrategy; import org.apache.openjpa.jdbc.meta.ValueMapping; +import org.apache.openjpa.jdbc.meta.ValueMappingImpl; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.ColumnIO; +import org.apache.openjpa.kernel.ObjectIdStateManager; import org.apache.openjpa.kernel.OpenJPAStateManager; +import org.apache.openjpa.kernel.StateManagerImpl; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.util.MetaDataException; @@ -149,6 +153,8 @@ public abstract class EmbedValueHandler OpenJPAStateManager embedSm = (OpenJPAStateManager) ((PersistenceCapable)cval).pcGetStateManager(); idx = toDataStoreValue1(embedSm, val, store, cols, rvals, idx); + } else if (cval == null) { + idx = toDataStoreValue1(null, val, store, cols, rvals, idx); } } @@ -209,8 +215,13 @@ public abstract class EmbedValueHandler embed = (Embeddable) fms[i].getStrategy(); if (vm1.getEmbeddedMapping() != null) { + if (em instanceof StateManagerImpl) { em1 = store.getContext().embed(null, null, em, vm1); idx = toObjectValue1(em1, vm1, val, store, fetch, cols, idx); + } else if (em instanceof ObjectIdStateManager) { + em1 = new ObjectIdStateManager(null, null, vm1); + idx = toObjectValue1(em1, vm1, val, store, null, getColumns(fms[i]), idx); + } cval = em1.getManagedInstance(); } else { ecols = embed.getColumns(); @@ -227,13 +238,45 @@ public abstract class EmbedValueHandler } } - if (store != null) + if (store != null && em instanceof StateManagerImpl) embed.loadEmbedded(em, store, fetch, cval); else { + if (!(em instanceof ObjectIdStateManager)) cval = embed.toEmbeddedObjectValue(cval); em.store(fms[i].getIndex(), cval); } } return idx; } + private Column[] getColumns(FieldMapping fm) { + List colList = new ArrayList(); + getEmbeddedIdCols(fm, colList); + Column[] cols = new Column[colList.size()]; + int i = 0; + for (Column col : colList) { + cols[i++] = col; + } + return cols; + } + + public static void getEmbeddedIdCols(FieldMapping fmd, List cols) { + ClassMapping embed = fmd.getEmbeddedMapping(); + FieldMapping[] fmds = embed.getFieldMappings(); + for (int i = 0; i < fmds.length; i++) { + if (fmds[i].getValue().getEmbeddedMetaData() == null) { + getIdColumns(fmds[i], cols); + } else { + getEmbeddedIdCols(fmd, cols); + } + } + } + + public static void getIdColumns(FieldMapping fmd, List cols) { + Column[] pkCols = ((ValueMappingImpl)fmd.getValue()).getColumns(); + for (int j = 0; j < pkCols.length; j++) { + Column newCol = new Column(); + newCol.setName(pkCols[j].getName()); + cols.add(newCol); + } + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java index 2d5c7a671..1eb49f5c9 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java @@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -27,7 +28,6 @@ import java.util.Set; import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.enhance.ReflectingPersistenceCapable; -import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.ClassMapping; @@ -201,24 +201,26 @@ public class RelationFieldStrategy } private List getMappedByIdColumns(FieldMapping pk) { - ClassMetaData embeddedId = ((ValueMappingImpl)pk.getValue()).getEmbeddedMetaData(); + ClassMetaData embeddedId = ((ValueMappingImpl)pk.getValue()). + getEmbeddedMetaData(); Column[] pkCols = null; + List cols = new ArrayList(); + String mappedByIdValue = field.getMappedByIdValue(); if (embeddedId != null) { FieldMetaData[] fmds = embeddedId.getFields(); for (int i = 0; i < fmds.length; i++) { - if (fmds[i].getName().equals(field.getMappedByIdValue())) { - pkCols = ((ValueMappingImpl)fmds[i].getValue()).getColumns(); - break; + if ((fmds[i].getName().equals(mappedByIdValue)) || + mappedByIdValue.length() == 0) { + if (fmds[i].getValue().getEmbeddedMetaData() != null) { + EmbedValueHandler.getEmbeddedIdCols((FieldMapping)fmds[i], cols); + } else { + EmbedValueHandler.getIdColumns((FieldMapping)fmds[i], cols); } } } - List cols = new ArrayList(); - for (int i = 0; i < pkCols.length; i++) { - Column newCol = new Column(); - newCol.setName(pkCols[i].getName()); - cols.add(newCol); + return cols; } - return cols; + return Collections.EMPTY_LIST; } /** diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java index 056ecc5fd..ec7d5a4cd 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java @@ -60,6 +60,7 @@ import org.apache.openjpa.util.Exceptions; import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.InvalidStateException; +import org.apache.openjpa.util.ObjectId; import org.apache.openjpa.util.ObjectNotFoundException; import org.apache.openjpa.util.OpenJPAId; import org.apache.openjpa.util.ProxyManager; @@ -148,6 +149,7 @@ public class StateManagerImpl // information about the owner of this instance, if it is embedded private StateManagerImpl _owner = null; private int _ownerIndex = -1; + private int _mappedByIdValueFrom = -1; private transient ReentrantLock _instanceLock = null; @@ -301,7 +303,12 @@ public class StateManagerImpl if (fmds[i].isPrimaryKey() || fmds[i].getManagement() != fmds[i].MANAGE_PERSISTENT) _loaded.set(i); - + + if (_meta.getIdentityType() == ClassMetaData.ID_APPLICATION && + fmds[i].getMappedByIdValue() != null && + ((ObjectId)_id).getId() == null) { + _mappedByIdValueFrom = fmds[i].getIndex(); + } // record whether there are any managed inverse fields if (_broker.getInverseManager() != null && fmds[i].getInverseMetaDatas().length > 0) @@ -3272,4 +3279,8 @@ public class StateManagerImpl pc.pcReplaceStateManager(this); return pc; } + + public int getMappedByIdValueFrom() { + return _mappedByIdValueFrom; + } } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java index 49b14cad4..7d649b709 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java @@ -565,7 +565,7 @@ public class FieldMetaData */ public Class getObjectIdFieldType() { ClassMetaData relmeta = getDeclaredTypeMetaData(); - if (relmeta == null) + if (relmeta == null || getValue().isEmbedded()) return getDeclaredType(); switch (relmeta.getIdentityType()) { case ClassMetaData.ID_DATASTORE: 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 32c2c7b4c..84022384d 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 @@ -491,6 +491,10 @@ public class ApplicationIds { } return true; } + + public static void setKey(ObjectId fromId, ObjectId toId) { + toId.setId(fromId.getId()); + } /** * Helper class used to transfer pk values to/from application oids. diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent2.java new file mode 100644 index 000000000..f596e56a8 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent2.java @@ -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="DEP2_MBI") +public class Dependent2 { + @EmbeddedId + DependentId2 id; + + @MappedById("empPK") + @ManyToOne Employee2 emp; + + public Employee2 getEmp() { + return emp; + } + + public void setEmp(Employee2 emp) { + this.emp = emp; + } + + public DependentId2 getId() { + return id; + } + + public void setId(DependentId2 id) { + this.id = id; + } + + public boolean equals(Object o) { + if (o == null) return false; + if (!(o instanceof Dependent2)) return false; + Dependent2 d0 = (Dependent2)o; + DependentId2 id0 = d0.getId(); + if (id == null && id0 != null) return false; + if (!id.equals(id0)) return false; + Employee2 e0 = d0.getEmp(); + if (emp != null && !emp.equals(e0)) return false; + if (emp == null && e0 != null) return false; + return true; + } + + public int hashCode() { + int ret = 0; + ret = ret * 31 + id.hashCode(); + ret = ret * 31 + emp.hashCode(); + return ret; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId2.java new file mode 100644 index 000000000..b3befae75 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId2.java @@ -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.*; + +@Embeddable +public class DependentId2 { + String name; + EmployeeId2 empPK; + + public DependentId2() {} + + public DependentId2(String name, EmployeeId2 empPK) { + this.name = name; + this.empPK = empPK; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setEmpPK(EmployeeId2 empPK) { + this.empPK = empPK; + } + + public EmployeeId2 getEmpPK() { + return empPK; + } + + public boolean equals(Object o) { + if (o == null) return false; + if (!(o instanceof DependentId2)) return false; + DependentId2 d = (DependentId2)o; + if (!empPK.equals(d.getEmpPK())) return false; + if (name != null && !name.equals(d.getName())) return false; + if (name == null && d.getName() != null) return false; + return true; + } + + public int hashCode() { + int ret = 0; + if (empPK != null) + ret = ret * 31 + empPK.hashCode(); + ret = ret * 31 + name.hashCode(); + return ret; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee2.java new file mode 100644 index 000000000..6c095efc9 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee2.java @@ -0,0 +1,78 @@ +/* + * 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.*; + +import java.util.*; + +@Entity +@Table(name="EMP2_MBI") +public class Employee2 { + @EmbeddedId + EmployeeId2 empId; + + @OneToMany(mappedBy="emp") + List dependents = new ArrayList(); + + public EmployeeId2 getEmpId() { + return empId; + } + + public void setEmpId(EmployeeId2 empId) { + this.empId = empId; + } + + public List getDependents() { + return dependents; + } + + public void setDependents(List dependents) { + this.dependents = dependents; + } + + public void addDependent(Dependent2 d) { + dependents.add(d); + } + + public boolean equals(Object o) { + if (o == null) return false; + if (!(o instanceof Employee2)) return false; + Employee2 e0 = (Employee2)o; + EmployeeId2 eid0 = e0.getEmpId(); + List ds0 = e0.getDependents(); + if (!empId.equals(eid0)) return false; + if (ds0 != null && ds0.size() != 0 && dependents == null) return false; + if (ds0 == null && dependents != null && dependents.size() != 0) return false; + if (ds0 == null && dependents == null) return true; + if (ds0 != null && dependents != null) { + if (ds0.size() != dependents.size()) return false; + } + return true; + } + + public int hashCode() { + int ret = 0; + ret = ret * 31 + empId.hashCode(); + for (Dependent2 d : dependents) { + ret = ret * 31 +d.id.hashCode(); + } + return ret; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId2.java new file mode 100644 index 000000000..6b9c602fe --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId2.java @@ -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.*; + +@Embeddable +public class EmployeeId2 { + String firstName; + String lastName; + + public EmployeeId2() {} + + public EmployeeId2(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 EmployeeId2)) return false; + EmployeeId2 eid = (EmployeeId2)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; + ret = ret * 31 + firstName.hashCode(); + ret = ret * 31 + lastName.hashCode(); + return ret; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory1.java new file mode 100644 index 000000000..2bf70dbac --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/MedicalHistory1.java @@ -0,0 +1,78 @@ +/* + * 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="MED1_MBI") +public class MedicalHistory1 { + String name; + + @EmbeddedId + PersonId1 id; + + @MappedById + @OneToOne Person1 patient; + + public PersonId1 getId() { + return id; + } + + public void setId(PersonId1 id) { + this.id = id; + } + + public Person1 getPatient() { + return patient; + } + + public void setPatient(Person1 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 MedicalHistory1)) return false; + MedicalHistory1 m0 = (MedicalHistory1)o; + String name0 = m0.getName(); + if (name != null && !name.equals(name0)) return false; + if (name == null && name0 != null) return false; + Person1 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.hashCode(); + return ret; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person1.java new file mode 100644 index 000000000..bf0c99b9b --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Person1.java @@ -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="PER1_MBI") +public class Person1 { + @EmbeddedId + PersonId1 id; + + @OneToOne(mappedBy="patient") + MedicalHistory1 medical; + + public PersonId1 getId() { + return id; + } + + public void setId(PersonId1 id) { + this.id = id; + } + + public MedicalHistory1 getMedical() { + return medical; + } + + public void setMedical(MedicalHistory1 medical) { + this.medical = medical; + } + + public boolean equals(Object o) { + if (o == null) return false; + if (!(o instanceof Person1)) return false; + Person1 p0 = (Person1)o; + PersonId1 id0 = p0.getId(); + MedicalHistory1 medical0 = p0.getMedical(); + if (id != null && !id.equals(id0)) return false; + if (medical != null && medical0 != null && + !medical.getId().equals(medical0.getId())) 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 + id.hashCode(); + if (medical != null) + ret = ret * 31 + medical.hashCode(); + return ret; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId1.java new file mode 100644 index 000000000..8808048cf --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/PersonId1.java @@ -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; +import javax.persistence.*; + +@Embeddable +public class PersonId1 { + String firstName; + String lastName; + + public PersonId1() {} + + public PersonId1(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 PersonId1)) return false; + PersonId1 eid = (PersonId1)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; + ret = ret * 31 + firstName.hashCode(); + ret = ret * 31 + lastName.hashCode(); + return ret; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java index 445d61579..407a7b5d6 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestMappedById.java @@ -18,7 +18,6 @@ */ package org.apache.openjpa.persistence.enhance.identity; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,76 +31,106 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase; public class TestMappedById extends SingleEMFTestCase { public int numEmployees = 4; public int numDependentsPerEmployee = 2; - public List namedQueries = new ArrayList(); - public Map emps = new HashMap(); - public Map deps = new HashMap(); + public int numPersons = 4; - public int eId = 1; - public int dId = 1; + public Map emps1 = new HashMap(); + public Map deps1 = new HashMap(); + public Map emps2 = new HashMap(); + public Map deps2 = new HashMap(); + public Map persons1 = new HashMap(); + public Map medicals1 = + new HashMap(); + + public int eId1 = 1; + public int dId1 = 1; + public int eId2 = 1; + public int dId2 = 1; + public int pId1 = 1; + public int mId1 = 1; public void setUp() throws Exception { super.setUp(DROP_TABLES, Dependent1.class, Employee1.class, - DependentId1.class); + DependentId1.class, Dependent2.class, Employee2.class, + DependentId2.class, EmployeeId2.class, MedicalHistory1.class, + Person1.class, PersonId1.class); } /** - * This is a spec 2.4.1.2 Example 1, case(b) + * This is spec 2.4.1.2 Example 1, case(b) */ public void testMappedById1() { - createObj(); - findObj(); - queryObj(); + createObj1(); + findObj1(); + queryObj1(); } - public void createObj() { + /** + * This is spec 2.4.1.2 Example 3, case(b) + */ + public void testMappedById2() { + createObj2(); + findObj2(); + queryObj2(); + } + + /** + * This is spec 2.4.1.2 Example 5, case(b) + */ + public void testMappedById3() { + createObj3(); + findObj3(); + queryObj3(); + } + + public void createObj1() { EntityManager em = emf.createEntityManager(); EntityTransaction tran = em.getTransaction(); for (int i = 0; i < numEmployees; i++) - createEmployee(em, eId++); + createEmployee1(em, eId1++); tran.begin(); em.flush(); tran.commit(); em.close(); } - public Employee1 createEmployee(EntityManager em, int id) { + public Employee1 createEmployee1(EntityManager em, int id) { Employee1 e = new Employee1(); e.setEmpId(id); e.setName("emp_" + id); for (int i = 0; i < numDependentsPerEmployee; i++) { - Dependent1 d = createDependent(em, dId++, e); + Dependent1 d = createDependent1(em, dId1++, e); e.addDependent(d); em.persist(d); } em.persist(e); - emps.put(id, e); + emps1.put(id, e); return e; } - public Dependent1 createDependent(EntityManager em, int id, Employee1 e) { + public Dependent1 createDependent1(EntityManager em, int id, Employee1 e) { Dependent1 d = new Dependent1(); DependentId1 did = new DependentId1(); did.setName("dep_" + id); d.setId(did); d.setEmp(e); - deps.put(did.getName(), d); + deps1.put(did.getName(), d); return d; } - public void findObj() { + public void findObj1() { EntityManager em = emf.createEntityManager(); Employee1 e = em.find(Employee1.class, 1); List ds = e.getDependents(); assertEquals(numDependentsPerEmployee, ds.size()); - Employee1 e0 = emps.get(1); + Employee1 e0 = emps1.get(1); assertEquals(e0, e); } - public void queryObj() { - queryDependent(); + public void queryObj1() { + queryDependent1(); } - public void queryDependent() { + public void queryDependent1() { EntityManager em = emf.createEntityManager(); EntityTransaction tran = em.getTransaction(); tran.begin(); @@ -109,17 +138,166 @@ public class TestMappedById extends SingleEMFTestCase { Query q = em.createQuery(jpql); List ds = q.getResultList(); for (Dependent1 d : ds) { - assertDependent(d); + assertDependent1(d); } tran.commit(); em.close(); } - public void assertDependent(Dependent1 d) { + public void assertDependent1(Dependent1 d) { DependentId1 id = d.getId(); - Dependent1 d0 = deps.get(id.getName()); + Dependent1 d0 = deps1.get(id.getName()); if (d0.id.empPK == 0) d0.id.empPK = d0.emp.getEmpId(); assertEquals(d0, d); } + + public void createObj2() { + EntityManager em = emf.createEntityManager(); + EntityTransaction tran = em.getTransaction(); + for (int i = 0; i < numEmployees; i++) + createEmployee2(em, eId2++); + tran.begin(); + em.flush(); + tran.commit(); + em.close(); + } + + public Employee2 createEmployee2(EntityManager em, int id) { + Employee2 e = new Employee2(); + e.setEmpId(new EmployeeId2("f_" + id, "l_" + id)); + for (int i = 0; i < numDependentsPerEmployee; i++) { + Dependent2 d = createDependent2(em, dId2++, e); + e.addDependent(d); + em.persist(d); + } + em.persist(e); + emps2.put(id, e); + return e; + } + + public Dependent2 createDependent2(EntityManager em, int id, Employee2 e) { + Dependent2 d = new Dependent2(); + DependentId2 did = new DependentId2(); + did.setName("dep_" + id); + d.setEmp(e); + d.setId(did); + em.persist(d); + deps2.put(did.getName(), d); + return d; + } + + public void findObj2() { + EntityManager em = emf.createEntityManager(); + Employee2 e = em.find(Employee2.class, new EmployeeId2("f_1", "l_1")); + List ds = e.getDependents(); + assertEquals(numDependentsPerEmployee, ds.size()); + Employee2 e0 = emps2.get(1); + assertEquals(e0, e); + } + + public void queryObj2() { + queryDependent2(); + } + public void queryDependent2() { + EntityManager em = emf.createEntityManager(); + EntityTransaction tran = em.getTransaction(); + String jpql = "select d from Dependent2 d where d.id.name = 'dep_1' AND d.id.empPK.firstName = 'f_1'"; + Query q = em.createQuery(jpql); + List ds = q.getResultList(); + for (Dependent2 d : ds) { + assertDependent2(d); + } + + jpql = "select d from Dependent2 d where d.id.name = 'dep_1' AND d.emp.empId.firstName = 'f_1'"; + q = em.createQuery(jpql); + ds = q.getResultList(); + for (Dependent2 d : ds) { + assertDependent2(d); + } + em.close(); + } + + public void assertDependent2(Dependent2 d) { + DependentId2 did = d.getId(); + Dependent2 d0 = deps2.get(did.getName()); + DependentId2 did0 = d0.getId(); + did0.setEmpPK(d0.getEmp().getEmpId()); + assertEquals(d0, d); + } + + public void createObj3() { + EntityManager em = emf.createEntityManager(); + EntityTransaction tran = em.getTransaction(); + for (int i = 0; i < numPersons; i++) + createPerson1(em, pId1++); + tran.begin(); + em.flush(); + tran.commit(); + em.close(); + } + + public Person1 createPerson1(EntityManager em, int id) { + Person1 p = new Person1(); + PersonId1 pid = new PersonId1(); + pid.setFirstName("f_" + id); + pid.setLastName("l_" + id); + p.setId(pid); + MedicalHistory1 m = createMedicalHistory1(em, mId1++); + m.setPatient(p); + p.setMedical(m); + em.persist(m); + em.persist(p); + persons1.put(pid.getFirstName(), p); + medicals1.put(m.getPatient().getId().getFirstName(), m); + return p; + } + + public MedicalHistory1 createMedicalHistory1(EntityManager em, int id) { + MedicalHistory1 m = new MedicalHistory1(); + m.setName("medical_" + id); + return m; + } + + public void findObj3() { + EntityManager em = emf.createEntityManager(); + PersonId1 pid = new PersonId1(); + pid.setFirstName("f_1"); + pid.setLastName("l_1"); + Person1 p = em.find(Person1.class, pid); + Person1 p0 = persons1.get(pid.getFirstName()); + assertEquals(p0, p); + } + + public void queryObj3() { + queryMedicalHistory1(); + } + + public void queryMedicalHistory1() { + EntityManager em = emf.createEntityManager(); + EntityTransaction tran = em.getTransaction(); + String firstName = "f_1"; + tran.begin(); + String jpql = "select m from MedicalHistory1 m where m.patient.id.firstName = '" + firstName + "'"; + Query q = em.createQuery(jpql); + List ms = q.getResultList(); + for (MedicalHistory1 m : ms) { + assertMedicalHistory(m, firstName); + } + + jpql = "select m from MedicalHistory1 m where m.id.firstName = '" + firstName + "'"; + q = em.createQuery(jpql); + ms = q.getResultList(); + for (MedicalHistory1 m : ms) { + assertMedicalHistory(m, firstName); + } + + tran.commit(); + em.close(); + } + + public void assertMedicalHistory(MedicalHistory1 m, String firstName) { + MedicalHistory1 m0 = medicals1.get(firstName); + assertEquals(m0, m); + } }