OPENJPA-715. Committing the testcase provided by Ekin Sokmen and the patch provided by Fay Wang. Committing the change for both the 1.2.x service stream and 1.3.0 snapshot (trunk).

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@693287 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Kevin W. Sutter 2008-09-08 21:34:26 +00:00
parent 8e6db6cb65
commit 4aa64410ad
4 changed files with 343 additions and 0 deletions

View File

@ -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.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Version;
@Entity
public class ChainEntityA {
@Id
@GeneratedValue
private long aId;
@Version
private Integer optLock;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
protected Set<ChainEntityB> chainEntityBSet;
public ChainEntityA () {
super ();
}
public void addChildEntityB (ChainEntityB bean) {
if (null == chainEntityBSet)
chainEntityBSet = new LinkedHashSet<ChainEntityB> ();
chainEntityBSet.add (bean);
}
public Collection<ChainEntityB> getChildren () {
if (null == chainEntityBSet)
chainEntityBSet = new LinkedHashSet<ChainEntityB> ();
return chainEntityBSet;
}
private String name;
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
public long getId () {
return aId;
}
public void setId (long id) {
this.aId = id;
}
}

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.relations;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;
@Entity
public class ChainEntityB {
@Id
@GeneratedValue
private long bId;
@Version
private Integer optLock;
//cascade = CascadeType.ALL,
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "chainEntityB")
protected Set<ChainEntityC> chainEntityCSet = null;
public void addChainEntityC (ChainEntityC bean) {
if (null == chainEntityCSet)
chainEntityCSet = new LinkedHashSet<ChainEntityC> ();
chainEntityCSet.add (bean);
bean.setChainEntityB (this);
}
public Collection<ChainEntityC> getChainEntityCSet () {
if (null == chainEntityCSet)
chainEntityCSet = new LinkedHashSet<ChainEntityC> ();
return chainEntityCSet;
}
private String name;
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
public long getId () {
return bId;
}
public void setId (long id) {
this.bId = id;
}
}

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.relations;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Version;
@Entity
public class ChainEntityC {
@Id
@GeneratedValue
private long cId;
@Version
private Integer optLock;
@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
protected ChainEntityB chainEntityB;
@Basic
protected long chainEntityBId;
public void setChainEntityB (ChainEntityB b) {
this.chainEntityB = b;
// this.chainEntityBId = null == b ? 0 : b.getId ();
}
private String name;
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
public long getId () {
return cId;
}
public void setId (long id) {
this.cId = id;
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.EntityManager;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestChainEntities extends SingleEMFTestCase {
/*
* Set this magical number to 3 or less to avoid the error.
*/
private static final int MAGICAL_NUMBER = 50;
long aid;
public void setUp () {
setUp (ChainEntityA.class, ChainEntityB.class, ChainEntityC.class);
// Create A
ChainEntityA a = new ChainEntityA ();
a.setName ("TEST_A");
// Persist A
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
em.persist (a);
aid = a.getId ();
em.getTransaction ().commit ();
em.close ();
System.out.println ("ChainEntityA id = " + aid);
}
public void testChainEntities () {
chainUpdate ();
}
protected void chainUpdate () {
// Get A
ChainEntityA a = getA ();
// Create B
ChainEntityB b = new ChainEntityB ();
b.setName ("Test_B_");
ChainEntityC c;
/*
* Create and add C to B. Increasing the number of iterations (number of
* ChainEntityC) increases the probability to get the unique key
* constraint violation error.
*/
for (int i = 1; i <= MAGICAL_NUMBER; i++) {
c = new ChainEntityC ();
c.setName ("Test_C_" + i);
b.addChainEntityC (c);
}
a.addChildEntityB (b);
// dump (a); // debug
// Merge A
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
a = em.merge (a);
/*
* workaround: Uncommenting following line is a workaround. If we
* retrive Ids of ChainEntityC objects after merge but before commit we
* don't get the error.
*/
//dump (a);
em.getTransaction ().commit ();
em.close ();
// dump (getA ()); // debug
}
/**
* Get created ChainEntityA using aid field.
*
* @return
*/
protected ChainEntityA getA () {
EntityManager em = emf.createEntityManager ();
ChainEntityA a = em.find (ChainEntityA.class, aid);
em.close ();
return a;
}
/**
* Print the object graph of given ChainEntityA to System.out
*
* @param testA
*/
protected void dump (ChainEntityA testA) {
System.out.println ("-------");
System.out.println (testA.getName () + "[" + testA.getId () + "]");
for (ChainEntityB testB : testA.getChildren ()) {
System.out.println (testB.getName () + "[" + testB.getId () + "]");
for (ChainEntityC testC : testB.getChainEntityCSet ()) {
System.out.println (testC.getName () + "[" + testC.getId ()
+ "]");
}
}
System.out.println ("-------");
}
}