OPENJPA-871: MappedById support (spec 2.4.1.2 Ex3b, 5b)

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@743437 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-02-11 18:19:13 +00:00
parent 897a912013
commit 1b7ff075c9
14 changed files with 798 additions and 40 deletions

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.strats.NoneFieldStrategy; 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.jdbc.sql.SelectExecutor;
import org.apache.openjpa.kernel.FetchConfiguration; import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.ApplicationIds;
import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.MetaDataException; import org.apache.openjpa.util.MetaDataException;
import org.apache.openjpa.util.ObjectId;
/** /**
* Specialization of metadata for relational databases. * Specialization of metadata for relational databases.
@ -587,6 +591,19 @@ public class FieldMapping
public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm) public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException { 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); assertStrategy().insert(sm, store, rm);
} }

View File

@ -25,13 +25,17 @@ import java.util.List;
import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; 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.Embeddable;
import org.apache.openjpa.jdbc.meta.FieldMapping; import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.FieldStrategy; import org.apache.openjpa.jdbc.meta.FieldStrategy;
import org.apache.openjpa.jdbc.meta.ValueMapping; 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.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO; import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.kernel.ObjectIdStateManager;
import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.MetaDataException; import org.apache.openjpa.util.MetaDataException;
@ -149,6 +153,8 @@ public abstract class EmbedValueHandler
OpenJPAStateManager embedSm = (OpenJPAStateManager) OpenJPAStateManager embedSm = (OpenJPAStateManager)
((PersistenceCapable)cval).pcGetStateManager(); ((PersistenceCapable)cval).pcGetStateManager();
idx = toDataStoreValue1(embedSm, val, store, cols, rvals, idx); 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(); embed = (Embeddable) fms[i].getStrategy();
if (vm1.getEmbeddedMapping() != null) { if (vm1.getEmbeddedMapping() != null) {
if (em instanceof StateManagerImpl) {
em1 = store.getContext().embed(null, null, em, vm1); em1 = store.getContext().embed(null, null, em, vm1);
idx = toObjectValue1(em1, vm1, val, store, fetch, cols, idx); 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(); cval = em1.getManagedInstance();
} else { } else {
ecols = embed.getColumns(); 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); embed.loadEmbedded(em, store, fetch, cval);
else { else {
if (!(em instanceof ObjectIdStateManager))
cval = embed.toEmbeddedObjectValue(cval); cval = embed.toEmbeddedObjectValue(cval);
em.store(fms[i].getIndex(), cval); em.store(fms[i].getIndex(), cval);
} }
} }
return idx; return idx;
} }
private Column[] getColumns(FieldMapping fm) {
List<Column> colList = new ArrayList<Column>();
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);
}
}
} }

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -27,7 +28,6 @@ import java.util.Set;
import org.apache.openjpa.enhance.PersistenceCapable; import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.ReflectingPersistenceCapable; 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.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -201,24 +201,26 @@ public class RelationFieldStrategy
} }
private List getMappedByIdColumns(FieldMapping pk) { private List getMappedByIdColumns(FieldMapping pk) {
ClassMetaData embeddedId = ((ValueMappingImpl)pk.getValue()).getEmbeddedMetaData(); ClassMetaData embeddedId = ((ValueMappingImpl)pk.getValue()).
getEmbeddedMetaData();
Column[] pkCols = null; Column[] pkCols = null;
List cols = new ArrayList();
String mappedByIdValue = field.getMappedByIdValue();
if (embeddedId != null) { if (embeddedId != null) {
FieldMetaData[] fmds = embeddedId.getFields(); FieldMetaData[] fmds = embeddedId.getFields();
for (int i = 0; i < fmds.length; i++) { for (int i = 0; i < fmds.length; i++) {
if (fmds[i].getName().equals(field.getMappedByIdValue())) { if ((fmds[i].getName().equals(mappedByIdValue)) ||
pkCols = ((ValueMappingImpl)fmds[i].getValue()).getColumns(); mappedByIdValue.length() == 0) {
break; if (fmds[i].getValue().getEmbeddedMetaData() != null) {
EmbedValueHandler.getEmbeddedIdCols((FieldMapping)fmds[i], cols);
} else {
EmbedValueHandler.getIdColumns((FieldMapping)fmds[i], cols);
} }
} }
} }
List cols = new ArrayList(); return cols;
for (int i = 0; i < pkCols.length; i++) {
Column newCol = new Column();
newCol.setName(pkCols[i].getName());
cols.add(newCol);
} }
return cols; return Collections.EMPTY_LIST;
} }
/** /**

View File

@ -60,6 +60,7 @@ import org.apache.openjpa.util.Exceptions;
import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.InvalidStateException; import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.ObjectId;
import org.apache.openjpa.util.ObjectNotFoundException; import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAId; import org.apache.openjpa.util.OpenJPAId;
import org.apache.openjpa.util.ProxyManager; import org.apache.openjpa.util.ProxyManager;
@ -148,6 +149,7 @@ public class StateManagerImpl
// information about the owner of this instance, if it is embedded // information about the owner of this instance, if it is embedded
private StateManagerImpl _owner = null; private StateManagerImpl _owner = null;
private int _ownerIndex = -1; private int _ownerIndex = -1;
private int _mappedByIdValueFrom = -1;
private transient ReentrantLock _instanceLock = null; private transient ReentrantLock _instanceLock = null;
@ -302,6 +304,11 @@ public class StateManagerImpl
|| fmds[i].getManagement() != fmds[i].MANAGE_PERSISTENT) || fmds[i].getManagement() != fmds[i].MANAGE_PERSISTENT)
_loaded.set(i); _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 // record whether there are any managed inverse fields
if (_broker.getInverseManager() != null if (_broker.getInverseManager() != null
&& fmds[i].getInverseMetaDatas().length > 0) && fmds[i].getInverseMetaDatas().length > 0)
@ -3272,4 +3279,8 @@ public class StateManagerImpl
pc.pcReplaceStateManager(this); pc.pcReplaceStateManager(this);
return pc; return pc;
} }
public int getMappedByIdValueFrom() {
return _mappedByIdValueFrom;
}
} }

View File

@ -565,7 +565,7 @@ public class FieldMetaData
*/ */
public Class getObjectIdFieldType() { public Class getObjectIdFieldType() {
ClassMetaData relmeta = getDeclaredTypeMetaData(); ClassMetaData relmeta = getDeclaredTypeMetaData();
if (relmeta == null) if (relmeta == null || getValue().isEmbedded())
return getDeclaredType(); return getDeclaredType();
switch (relmeta.getIdentityType()) { switch (relmeta.getIdentityType()) {
case ClassMetaData.ID_DATASTORE: case ClassMetaData.ID_DATASTORE:

View File

@ -492,6 +492,10 @@ public class ApplicationIds {
return true; 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. * Helper class used to transfer pk values to/from application oids.
*/ */

View File

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

View File

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

View File

@ -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<Dependent2> dependents = new ArrayList<Dependent2>();
public EmployeeId2 getEmpId() {
return empId;
}
public void setEmpId(EmployeeId2 empId) {
this.empId = empId;
}
public List<Dependent2> getDependents() {
return dependents;
}
public void setDependents(List<Dependent2> 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<Dependent2> 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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,6 @@
*/ */
package org.apache.openjpa.persistence.enhance.identity; package org.apache.openjpa.persistence.enhance.identity;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -32,76 +31,106 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestMappedById extends SingleEMFTestCase { public class TestMappedById extends SingleEMFTestCase {
public int numEmployees = 4; public int numEmployees = 4;
public int numDependentsPerEmployee = 2; public int numDependentsPerEmployee = 2;
public List<String> namedQueries = new ArrayList<String>(); public int numPersons = 4;
public Map<Integer, Employee1> emps = new HashMap<Integer, Employee1>();
public Map<String, Dependent1> deps = new HashMap<String, Dependent1>();
public int eId = 1; public Map<Integer, Employee1> emps1 = new HashMap<Integer, Employee1>();
public int dId = 1; public Map<String, Dependent1> deps1 = new HashMap<String, Dependent1>();
public Map<Integer, Employee2> emps2 = new HashMap<Integer, Employee2>();
public Map<String, Dependent2> deps2 = new HashMap<String, Dependent2>();
public Map<String, Person1> persons1 = new HashMap<String, Person1>();
public Map<String, MedicalHistory1> medicals1 =
new HashMap<String, MedicalHistory1>();
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 { public void setUp() throws Exception {
super.setUp(DROP_TABLES, Dependent1.class, Employee1.class, 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() { public void testMappedById1() {
createObj(); createObj1();
findObj(); findObj1();
queryObj(); 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(); EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction(); EntityTransaction tran = em.getTransaction();
for (int i = 0; i < numEmployees; i++) for (int i = 0; i < numEmployees; i++)
createEmployee(em, eId++); createEmployee1(em, eId1++);
tran.begin(); tran.begin();
em.flush(); em.flush();
tran.commit(); tran.commit();
em.close(); em.close();
} }
public Employee1 createEmployee(EntityManager em, int id) { public Employee1 createEmployee1(EntityManager em, int id) {
Employee1 e = new Employee1(); Employee1 e = new Employee1();
e.setEmpId(id); e.setEmpId(id);
e.setName("emp_" + id); e.setName("emp_" + id);
for (int i = 0; i < numDependentsPerEmployee; i++) { for (int i = 0; i < numDependentsPerEmployee; i++) {
Dependent1 d = createDependent(em, dId++, e); Dependent1 d = createDependent1(em, dId1++, e);
e.addDependent(d); e.addDependent(d);
em.persist(d); em.persist(d);
} }
em.persist(e); em.persist(e);
emps.put(id, e); emps1.put(id, e);
return 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(); Dependent1 d = new Dependent1();
DependentId1 did = new DependentId1(); DependentId1 did = new DependentId1();
did.setName("dep_" + id); did.setName("dep_" + id);
d.setId(did); d.setId(did);
d.setEmp(e); d.setEmp(e);
deps.put(did.getName(), d); deps1.put(did.getName(), d);
return d; return d;
} }
public void findObj() { public void findObj1() {
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
Employee1 e = em.find(Employee1.class, 1); Employee1 e = em.find(Employee1.class, 1);
List<Dependent1> ds = e.getDependents(); List<Dependent1> ds = e.getDependents();
assertEquals(numDependentsPerEmployee, ds.size()); assertEquals(numDependentsPerEmployee, ds.size());
Employee1 e0 = emps.get(1); Employee1 e0 = emps1.get(1);
assertEquals(e0, e); assertEquals(e0, e);
} }
public void queryObj() { public void queryObj1() {
queryDependent(); queryDependent1();
} }
public void queryDependent() { public void queryDependent1() {
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction(); EntityTransaction tran = em.getTransaction();
tran.begin(); tran.begin();
@ -109,17 +138,166 @@ public class TestMappedById extends SingleEMFTestCase {
Query q = em.createQuery(jpql); Query q = em.createQuery(jpql);
List<Dependent1> ds = q.getResultList(); List<Dependent1> ds = q.getResultList();
for (Dependent1 d : ds) { for (Dependent1 d : ds) {
assertDependent(d); assertDependent1(d);
} }
tran.commit(); tran.commit();
em.close(); em.close();
} }
public void assertDependent(Dependent1 d) { public void assertDependent1(Dependent1 d) {
DependentId1 id = d.getId(); DependentId1 id = d.getId();
Dependent1 d0 = deps.get(id.getName()); Dependent1 d0 = deps1.get(id.getName());
if (d0.id.empPK == 0) if (d0.id.empPK == 0)
d0.id.empPK = d0.emp.getEmpId(); d0.id.empPK = d0.emp.getEmpId();
assertEquals(d0, d); 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<Dependent2> 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<Dependent2> 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<MedicalHistory1> 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);
}
} }