mirror of https://github.com/apache/openjpa.git
OPENJPA-679 java.lang.ArrayIndexOutOfBoundsException may occur when a relation field is annotated as a primary key and a foreign key
Commit patch provided by Fay Wang git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@685042 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ffb59c35fc
commit
f4845dae9b
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.apache.openjpa.jdbc.meta;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -32,12 +30,12 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||
import org.apache.openjpa.enhance.Reflection;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCStore;
|
||||
import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy;
|
||||
import org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy;
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.jdbc.schema.ColumnIO;
|
||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||
|
@ -91,6 +89,7 @@ public class ClassMapping
|
|||
|
||||
// maps columns to joinables
|
||||
private final Map _joinables = Collections.synchronizedMap(new HashMap());
|
||||
private boolean redoPrimaryKeyColumns = false;
|
||||
|
||||
/**
|
||||
* Constructor. Supply described type and owning repository.
|
||||
|
@ -418,17 +417,25 @@ public class ClassMapping
|
|||
* class uses to link to its superclass table.
|
||||
*/
|
||||
public Column[] getPrimaryKeyColumns() {
|
||||
if (_cols.length == 0 && getIdentityType() == ID_APPLICATION
|
||||
&& isMapped()) {
|
||||
FieldMapping[] pks = getPrimaryKeyFieldMappings();
|
||||
Collection cols = new ArrayList(pks.length);
|
||||
Column[] fieldCols;
|
||||
for (int i = 0; i < pks.length; i++) {
|
||||
fieldCols = pks[i].getColumns();
|
||||
for (int j = 0; j < fieldCols.length; j++)
|
||||
cols.add(fieldCols[j]);
|
||||
if (getIdentityType() == ID_APPLICATION && isMapped()) {
|
||||
if (_cols.length == 0 || redoPrimaryKeyColumns) {
|
||||
FieldMapping[] pks = getPrimaryKeyFieldMappings();
|
||||
Collection cols = new ArrayList(pks.length);
|
||||
Column[] fieldCols;
|
||||
for (int i = 0; i < pks.length; i++) {
|
||||
fieldCols = pks[i].getColumns();
|
||||
if (fieldCols.length == 0) {
|
||||
// some pk columns depends on fk. At this moment,
|
||||
// the fk may not contain complete information.
|
||||
// need to redo the primary key again later on
|
||||
redoPrimaryKeyColumns = true;
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < fieldCols.length; j++)
|
||||
cols.add(fieldCols[j]);
|
||||
}
|
||||
_cols = (Column[]) cols.toArray(new Column[cols.size()]);
|
||||
}
|
||||
_cols = (Column[]) cols.toArray(new Column[cols.size()]);
|
||||
}
|
||||
return _cols;
|
||||
}
|
||||
|
@ -826,9 +833,27 @@ public class ClassMapping
|
|||
// recursion, then resolve all fields
|
||||
resolveNonRelationMappings();
|
||||
FieldMapping[] fms = getFieldMappings();
|
||||
for (int i = 0; i < fms.length; i++)
|
||||
if (fms[i].getDefiningMetaData() == this)
|
||||
for (int i = 0; i < fms.length; i++) {
|
||||
if (fms[i].getDefiningMetaData() == this) {
|
||||
if (fms[i].getForeignKey() != null &&
|
||||
fms[i].getStrategy() instanceof RelationFieldStrategy) {
|
||||
// set resolve mode to force this field mapping to be
|
||||
// resolved again. The need to resolve again occurs when
|
||||
// a primary key is a relation field with the foreign key
|
||||
// annotation. In this situation, this primary key field
|
||||
// mapping is resolved during the call to
|
||||
// resolveNonRelationMapping. Since it is a relation
|
||||
// field, the foreign key will be constructed. However,
|
||||
// the primary key of the parent entity may not have been
|
||||
// resolved yet, resulting in missing informaiton in the fk
|
||||
fms[i].setResolve(MODE_META);
|
||||
|
||||
// set strategy to null to force fk to be re-constructed
|
||||
fms[i].setStrategy(null, false);
|
||||
}
|
||||
fms[i].resolve(MODE_MAPPING);
|
||||
}
|
||||
}
|
||||
fms = getDeclaredUnmanagedFieldMappings();
|
||||
for (int i = 0; i < fms.length; i++)
|
||||
fms[i].resolve(MODE_MAPPING);
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
@Entity
|
||||
@IdClass(C.CId.class)
|
||||
@Table(name="C4")
|
||||
public class C {
|
||||
|
||||
@Id
|
||||
private String cId;
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
@Id
|
||||
private CM cm;
|
||||
|
||||
@OneToMany(mappedBy="c")
|
||||
private Set<D> ds = new HashSet<D>();
|
||||
|
||||
public C() {
|
||||
}
|
||||
|
||||
public String getCId() {
|
||||
return cId;
|
||||
}
|
||||
|
||||
public void setCId(String cId) {
|
||||
this.cId = cId;
|
||||
}
|
||||
|
||||
public CM getCm() {
|
||||
return cm;
|
||||
}
|
||||
|
||||
public void setCm(CM cm) {
|
||||
this.cm = cm;
|
||||
}
|
||||
|
||||
public Set<D> getDs() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
public void setDs(Set<D> ds) {
|
||||
this.ds = ds;
|
||||
}
|
||||
|
||||
public static class CId{
|
||||
String cId;
|
||||
CM.CMId cm;
|
||||
|
||||
public String getCId() {
|
||||
return cId;
|
||||
}
|
||||
public void setCId(String id) {
|
||||
cId = id;
|
||||
}
|
||||
|
||||
|
||||
public CM.CMId getCm() {
|
||||
return cm;
|
||||
}
|
||||
public void setCm(CM.CMId cm) {
|
||||
this.cm = cm;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || !(obj instanceof CId))
|
||||
return false;
|
||||
|
||||
CId id = (CId) obj;
|
||||
|
||||
return (this.getCId() == id.getCId() || (this.getCId() != null &&
|
||||
this.getCId().equals(id.getCId())))
|
||||
&& (this.getCm() == id.getCm() || (this.getCm() != null &&
|
||||
this.getCm().equals(id.getCm())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((this.getCId() != null) ? this.getCId().hashCode():0)
|
||||
^ ((this.getCm() != null)? this.getCm().hashCode():0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
@Entity
|
||||
@IdClass(CM.CMId.class)
|
||||
@Table(name="CM4")
|
||||
public class CM {
|
||||
|
||||
@Id
|
||||
private String cmId;
|
||||
|
||||
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="cm")
|
||||
private Set<C> cs = new HashSet<C>();
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
@Id
|
||||
private E e;
|
||||
|
||||
public CM() {
|
||||
}
|
||||
|
||||
public String getCmId() {
|
||||
return cmId;
|
||||
}
|
||||
|
||||
public void setCmId(String cmId) {
|
||||
this.cmId = cmId;
|
||||
}
|
||||
|
||||
public Set<C> getCs() {
|
||||
return cs;
|
||||
}
|
||||
|
||||
public void setCs(Set<C> cs) {
|
||||
this.cs = cs;
|
||||
}
|
||||
|
||||
public void addC(C c){
|
||||
cs.add(c);
|
||||
c.setCm(this);
|
||||
}
|
||||
|
||||
public E getE() {
|
||||
return e;
|
||||
}
|
||||
|
||||
public void setE(E e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public static class CMId{
|
||||
private String cmId;
|
||||
private String e;
|
||||
|
||||
public String getCmId() {
|
||||
return cmId;
|
||||
}
|
||||
public void setCmId(String id) {
|
||||
cmId = id;
|
||||
}
|
||||
|
||||
public String getE() {
|
||||
return e;
|
||||
}
|
||||
public void setE(String e) {
|
||||
this.e = e;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null && ! (obj instanceof CMId))
|
||||
return false;
|
||||
CMId id = (CMId) obj;
|
||||
return ( this.getCmId() == id.getCmId() ||
|
||||
(this.getCmId() != null && this.getCmId().equals(id.getCmId())))
|
||||
&& ( this.getE() == id.getE() || (this.getE() != null &&
|
||||
this.getE().equals(id.getE())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.getCmId() != null? this.getCmId().hashCode():0)
|
||||
^ (this.getE()!= null ? this.getE().hashCode():0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name="D4")
|
||||
@IdClass(D.CId.class)
|
||||
public class D {
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
private C c;
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String a;
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
@Id
|
||||
private VC vc;
|
||||
|
||||
public D() {
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public void setA(String a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public C getC() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public void setC(C c) {
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
public VC getVc() {
|
||||
return vc;
|
||||
}
|
||||
|
||||
public void setVc(VC vc) {
|
||||
this.vc = vc;
|
||||
}
|
||||
|
||||
|
||||
public static class CId{
|
||||
private String id;
|
||||
|
||||
private VC.VCId vc;
|
||||
|
||||
public VC.VCId getVc() {
|
||||
return vc;
|
||||
}
|
||||
public void setVc(VC.VCId vc) {
|
||||
this.vc = vc;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || ! (obj instanceof CId))
|
||||
return false;
|
||||
CId id = (CId) obj;
|
||||
return (this.getId() == id.getId() || (this.getId() != null &&
|
||||
this.getId().equals(id.getId())))
|
||||
&& (this.getVc() == id.getVc() || (this.getVc() != null &&
|
||||
this.getVc().equals(id.getVc())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.getId() != null ? this.getId().hashCode():0)
|
||||
^ (this.getVc() != null ? this.getVc().hashCode():0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="E4")
|
||||
public class E {
|
||||
|
||||
@Id
|
||||
private String eId;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "e")
|
||||
private Set<VCS> vcss = new HashSet<VCS>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "e")
|
||||
private Set<CM> cms = new HashSet<CM>();
|
||||
|
||||
public E() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Set<CM> getCms() {
|
||||
return cms;
|
||||
}
|
||||
|
||||
public void setCms(Set<CM> cms) {
|
||||
this.cms = cms;
|
||||
}
|
||||
|
||||
public String getEId() {
|
||||
return eId;
|
||||
}
|
||||
|
||||
public void setEId(String id) {
|
||||
eId = id;
|
||||
}
|
||||
|
||||
public Set<VCS> getVcss() {
|
||||
return vcss;
|
||||
}
|
||||
|
||||
public void setVcss(Set<VCS> vcss) {
|
||||
this.vcss = vcss;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
|
||||
public class TestRelationFieldAsPrimaryKeyAndForeignKey
|
||||
extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() {
|
||||
setUp(C.class, CM.class, D.class, E.class, VC.class, VCS.class);
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
List<E> es = (List<E>) em.createQuery(
|
||||
"Select e from E e").getResultList();
|
||||
for (E e : es)
|
||||
em.remove(e);
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
E e = new E();
|
||||
e.setEId("E1");
|
||||
e.setName("E1");
|
||||
|
||||
VC vc = new VC();
|
||||
vc.setVcId("VC1");
|
||||
|
||||
VCS vcset = new VCS();
|
||||
vcset.setVcsId("VCS1");
|
||||
vcset.setName("VCSET1");
|
||||
vcset.addVC(vc);
|
||||
vcset.setE(e);
|
||||
|
||||
C c = new C();
|
||||
c.setCId("C1");
|
||||
|
||||
CM cm = new CM();
|
||||
cm.setCmId("CM1");
|
||||
cm.setE(e);
|
||||
cm.addC(c);
|
||||
|
||||
D d = new D();
|
||||
d.setA("addr");
|
||||
d.setVc(vc);
|
||||
d.setId("IM1");
|
||||
|
||||
em.persist(e);
|
||||
em.persist(vc);
|
||||
em.persist(vcset);
|
||||
em.persist(c);
|
||||
em.persist(cm);
|
||||
em.persist(d);
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testUnboundEntities() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
VCS vcSet = new VCS();
|
||||
vcSet.setVcsId("VCSET2");
|
||||
vcSet.setName("VCSET2");
|
||||
try {
|
||||
em.persist(vcSet);
|
||||
em.getTransaction().commit();
|
||||
Assert.fail("didn't throw expected PersistenceException");
|
||||
} catch (Exception e) {
|
||||
// test pass
|
||||
} finally {
|
||||
if (em.getTransaction().isActive())
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
em.getTransaction().begin();
|
||||
VC vc = new VC();
|
||||
vc.setVcId("VC2");
|
||||
try {
|
||||
em.persist(vc);
|
||||
em.getTransaction().commit();
|
||||
Assert.fail("didn't throw expected PersistenceException");
|
||||
} catch (Exception e) {
|
||||
// test pass
|
||||
} finally {
|
||||
if (em.getTransaction().isActive())
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
em.getTransaction().begin();
|
||||
CM cm = new CM();
|
||||
cm.setCmId("CMID2");
|
||||
try {
|
||||
em.persist(cm);
|
||||
em.getTransaction().commit();
|
||||
Assert.fail("didn't throw expected PersistenceException");
|
||||
} catch (Exception e) {
|
||||
// test pass
|
||||
} finally {
|
||||
if (em.getTransaction().isActive())
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
em.getTransaction().begin();
|
||||
C c = new C();
|
||||
c.setCId("CID2");
|
||||
try {
|
||||
em.persist(c);
|
||||
em.getTransaction().commit();
|
||||
Assert.fail("didn't throw expected PersistenceException");
|
||||
} catch (Exception e) {
|
||||
// test pass
|
||||
} finally {
|
||||
if (em.getTransaction().isActive())
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testQuery() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
List<E> es = (List<E>) em.createQuery(
|
||||
"Select e from E e where e.name='E1'").getResultList();
|
||||
Assert.assertEquals(1, es.size());
|
||||
E e = (E) es.get(0);
|
||||
Assert.assertEquals("E1", e.getName());
|
||||
Assert.assertEquals(1, e.getVcss().size());
|
||||
Assert.assertEquals(1, e.getCms().size());
|
||||
Assert.assertEquals(1, e.getVcss().size());
|
||||
|
||||
// Get virtual container set and check that it has a reference to the
|
||||
// ensemble
|
||||
List<VCS> vcss = (List<VCS>) em.createQuery(
|
||||
"Select vcset from VCS vcset where vcset.vcsId='VCS1'")
|
||||
.getResultList();
|
||||
Assert.assertEquals(1, vcss.size());
|
||||
Assert.assertEquals(e, ((VCS) vcss.get(0)).getE());
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testDeletes() {
|
||||
// Remove VC set and check that all VCs belonging to that set are
|
||||
// deleted but not the ensemble itself
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
VCS vcset = (VCS) em.createQuery(
|
||||
"Select vcset from VCS vcset where vcset.vcsId='VCS1'")
|
||||
.getSingleResult();
|
||||
em.remove(vcset);
|
||||
em.getTransaction().commit();
|
||||
|
||||
// Get virtualContainer
|
||||
List<VC> vcs = (List<VC>) em.createQuery(
|
||||
"Select vc from VC vc where vc.vcId='VC1'")
|
||||
.getResultList();
|
||||
Assert.assertEquals(0, vcs.size());
|
||||
|
||||
// Make sure E and I are still there
|
||||
List<E> es = (List<E>) em.createQuery(
|
||||
"Select e from E e").getResultList();
|
||||
Assert.assertEquals(1, es.size());
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
List<E> es = (List<E>) em.createQuery(
|
||||
"Select e from E e").getResultList();
|
||||
for (E e : es) {
|
||||
em.remove(e);
|
||||
}
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.openjpa.persistence.relations.VCS.VCSId;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
@Entity
|
||||
@Table(name="VC4")
|
||||
@IdClass(VC.VCId.class)
|
||||
|
||||
public class VC {
|
||||
|
||||
@Id
|
||||
private String vcId;
|
||||
|
||||
// @ManyToOne
|
||||
// @ForeignKey
|
||||
// private I i;
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
@Id
|
||||
private VCS vcs;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "vc")
|
||||
private Set<D> ds = new HashSet<D>();
|
||||
|
||||
public VC() {
|
||||
}
|
||||
|
||||
public String getVcId() {
|
||||
return vcId;
|
||||
}
|
||||
|
||||
public void setVcId(String vcId) {
|
||||
this.vcId = vcId;
|
||||
}
|
||||
|
||||
public Set<D> getDs() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
public void setDs(Set<D> ds) {
|
||||
this.ds = ds;
|
||||
}
|
||||
|
||||
public VCS getVcs() {
|
||||
return vcs;
|
||||
}
|
||||
|
||||
public void setVcs(VCS vcs) {
|
||||
this.vcs = vcs;
|
||||
}
|
||||
|
||||
public static class VCId {
|
||||
private String vcId;
|
||||
|
||||
private VCSId vcs;
|
||||
|
||||
public String getVcId() {
|
||||
return vcId;
|
||||
}
|
||||
|
||||
public void setVcId(String vcId) {
|
||||
this.vcId = vcId;
|
||||
}
|
||||
|
||||
public VCSId getVcs() {
|
||||
return vcs;
|
||||
}
|
||||
|
||||
public void setVcs(VCSId vcs) {
|
||||
this.vcs = vcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || !(obj instanceof VCId))
|
||||
return false;
|
||||
VCId id = (VCId) obj;
|
||||
return (this.getVcId() == id.getVcId() ||
|
||||
(this.getVcId() == null &&
|
||||
this.getVcId().equals(id.getVcId()))) &&
|
||||
(this.getVcs() == id.getVcs() ||
|
||||
(this.getVcs() == null && this
|
||||
.getVcs().equals(id.getVcs())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.getVcId() != null ? this.getVcId().hashCode() : 0)
|
||||
^ (this.getVcs() != null ? this.getVcs().hashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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.relations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
@Entity
|
||||
@Table(name="VCS4")
|
||||
@IdClass(VCS.VCSId.class)
|
||||
public class VCS {
|
||||
|
||||
@Id
|
||||
private String vcsId;
|
||||
|
||||
@ManyToOne
|
||||
@ForeignKey
|
||||
@Id
|
||||
private E e;
|
||||
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy = "vcs")
|
||||
private Set<VC> vcs = new HashSet<VC>();
|
||||
|
||||
public VCS() {
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String getVcsId() {
|
||||
return vcsId;
|
||||
}
|
||||
|
||||
|
||||
public void setVcsId(String vcsId) {
|
||||
this.vcsId = vcsId;
|
||||
}
|
||||
|
||||
|
||||
public E getE() {
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
public void setE(E e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
|
||||
public Set<VC> getVcs() {
|
||||
return vcs;
|
||||
}
|
||||
|
||||
|
||||
public void setVcs(Set<VC> vcs) {
|
||||
this.vcs = vcs;
|
||||
}
|
||||
|
||||
public void addVC(VC vc){
|
||||
vcs.add(vc);
|
||||
vc.setVcs(this);
|
||||
}
|
||||
public static class VCSId{
|
||||
private String vcsId;
|
||||
private String e;
|
||||
|
||||
|
||||
public String getE() {
|
||||
return e;
|
||||
}
|
||||
|
||||
public void setE(String e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public String getVcsId() {
|
||||
return vcsId;
|
||||
}
|
||||
|
||||
public void setVcsId(String vcsId) {
|
||||
this.vcsId = vcsId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || ! (obj instanceof VCSId))
|
||||
return false;
|
||||
VCSId id = (VCSId) obj;
|
||||
return (this.getVcsId() == id.getVcsId() ||
|
||||
(this.getVcsId() != null &&
|
||||
this.getVcsId().equals(id.getVcsId())))
|
||||
&& (this.getE() == id.getE() || (this.getE() != null
|
||||
&& this.getE().equals(id.getE())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.getVcsId() != null ?this.getVcsId().hashCode():0)
|
||||
^ (this.getE() != null ? this.getE().hashCode():0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue