mirror of https://github.com/apache/openjpa.git
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:
parent
8e6db6cb65
commit
4aa64410ad
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 ("-------");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue