mirror of https://github.com/apache/openjpa.git
OPENJPA-39 test case. Also query fixes and fix to possible data corruption
issue (yikes!). git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@442388 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f56a7555a7
commit
1e95734015
|
@ -133,8 +133,9 @@ public class OperationOrderUpdateManager
|
|||
|| rel.getIndex() >= row.getIndex())
|
||||
continue;
|
||||
|
||||
// create an update to null the offending fk before deleting
|
||||
update = new RowImpl(row.getTable(), Row.ACTION_UPDATE);
|
||||
// create an update to null the offending fk before deleting. use
|
||||
// a primary row to be sure to copy delayed-flush pks/fks
|
||||
update = new PrimaryRow(row.getTable(), Row.ACTION_UPDATE, null);
|
||||
row.copyInto(update, true);
|
||||
update.setForeignKey(fks[i], row.getForeignKeyIO(fks[i]), null);
|
||||
if (updates == null)
|
||||
|
|
|
@ -288,12 +288,6 @@ class PCPath
|
|||
if (prev.op == Action.GET || prev.op == Action.GET_OUTER
|
||||
|| prev.op == Action.GET_KEY)
|
||||
return prev;
|
||||
|
||||
// break if we're getting to path portions that we copied from
|
||||
// our variable
|
||||
if (prev.op == Action.VAR || prev.op == Action.UNBOUND_VAR
|
||||
|| prev.op == Action.SUBQUERY)
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ class IdentityJoinable
|
|||
|
||||
public Object getJoinValue(OpenJPAStateManager sm, Column col,
|
||||
JDBCStore store) {
|
||||
return Numbers.valueOf(((Id) sm.getObjectId()).getId());
|
||||
Id id = (Id) sm.getObjectId();
|
||||
return (id == null) ? null : id.getIdObject();
|
||||
}
|
||||
|
||||
public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store,
|
||||
|
|
|
@ -243,12 +243,13 @@ public class RelationFieldStrategy
|
|||
throws SQLException {
|
||||
ForeignKey fk = field.getForeignKey();
|
||||
ColumnIO io = field.getColumnIO();
|
||||
if (!io.isAnyUpdatable(fk, true))
|
||||
if (fk.getDeleteAction() != ForeignKey.ACTION_NONE
|
||||
|| !io.isAnyUpdatable(fk, true))
|
||||
return;
|
||||
|
||||
// null inverse if not already enforced by fk
|
||||
if (field.getIndependentTypeMappings().length != 1)
|
||||
throw RelationStrategies.uninversable(field);
|
||||
|
||||
Row row = rm.getAllRows(fk.getTable(), Row.ACTION_UPDATE);
|
||||
row.setForeignKey(fk, io, null);
|
||||
row.whereForeignKey(fk, sm);
|
||||
|
|
|
@ -223,10 +223,12 @@ public abstract class RelationToManyInverseKeyFieldStrategy
|
|||
ValueMapping elem = field.getElementMapping();
|
||||
ColumnIO io = elem.getColumnIO();
|
||||
ForeignKey fk = elem.getForeignKey();
|
||||
if (!io.isAnyUpdatable(fk, true))
|
||||
if (fk.getDeleteAction() != ForeignKey.ACTION_NONE
|
||||
|| !io.isAnyUpdatable(fk, true))
|
||||
return;
|
||||
|
||||
// null any existing inverse columns that refer to this obj
|
||||
// if the fk doesn't enforce it, null any existing inverse columns
|
||||
// that refer to this obj
|
||||
assertInversable();
|
||||
Row row = rm.getAllRows(fk.getTable(), Row.ACTION_UPDATE);
|
||||
row.setForeignKey(fk, io, null);
|
||||
|
|
|
@ -24,7 +24,6 @@ import javax.persistence.Persistence;
|
|||
|
||||
import junit.framework.TestCase;
|
||||
import junit.textui.TestRunner;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
|
||||
/**
|
||||
* Perform basic operations on an inheritance hierarchy involving multiple
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package org.apache.openjpa.persistence.relations;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||
|
||||
@Entity
|
||||
public class CascadingOneManyChild {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToOne(optional=false)
|
||||
@JoinColumn(name="PARENT_ID")
|
||||
@ForeignKey
|
||||
private CascadingOneManyParent parent;
|
||||
|
||||
@Version
|
||||
private Integer optLock;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public CascadingOneManyParent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(CascadingOneManyParent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.apache.openjpa.persistence.relations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@Entity
|
||||
public class CascadingOneManyParent {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
|
||||
@OrderBy("name ASC")
|
||||
private List<CascadingOneManyChild> children =
|
||||
new ArrayList<CascadingOneManyChild>();
|
||||
|
||||
@Version
|
||||
private Integer optLock;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<CascadingOneManyChild> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void addChild(CascadingOneManyChild child) {
|
||||
child.setParent(this);
|
||||
children.add(child);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright 2006 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed 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.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import junit.textui.TestRunner;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
|
||||
|
||||
/**
|
||||
* Tests a cascading one-many backed by a foreign key.
|
||||
*
|
||||
* @author Abe White
|
||||
*/
|
||||
public class TestCascadingOneManyWithForeignKey
|
||||
extends TestCase {
|
||||
|
||||
private OpenJPAEntityManagerFactory emf;
|
||||
|
||||
public void setUp() {
|
||||
String types = CascadingOneManyParent.class.getName() + ";"
|
||||
+ CascadingOneManyChild.class.getName();
|
||||
Map props = new HashMap();
|
||||
props.put("openjpa.MetaDataFactory", "jpa(Types=" + types + ")");
|
||||
emf = (OpenJPAEntityManagerFactory) Persistence.
|
||||
createEntityManagerFactory("test", props);
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
if (emf == null)
|
||||
return;
|
||||
try {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.createQuery("delete from CascadingOneManyChild").executeUpdate();
|
||||
em.createQuery("delete from CascadingOneManyParent").
|
||||
executeUpdate();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
emf.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testPersist() {
|
||||
CascadingOneManyParent parent = new CascadingOneManyParent();
|
||||
parent.setName("parent");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
CascadingOneManyChild child = new CascadingOneManyChild();
|
||||
child.setName("child" + i);
|
||||
parent.addChild(child);
|
||||
}
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.persist(parent);
|
||||
em.getTransaction().commit();
|
||||
long id = parent.getId();
|
||||
assertEquals(2, parent.getChildren().size());
|
||||
assertEquals("child0", parent.getChildren().get(0).getName());
|
||||
assertEquals("child1", parent.getChildren().get(1).getName());
|
||||
em.close();
|
||||
|
||||
em = emf.createEntityManager();
|
||||
parent = em.find(CascadingOneManyParent.class, id);
|
||||
assertNotNull(parent);
|
||||
assertEquals("parent", parent.getName());
|
||||
assertEquals(2, parent.getChildren().size());
|
||||
assertEquals("child0", parent.getChildren().get(0).getName());
|
||||
assertEquals("child1", parent.getChildren().get(1).getName());
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testDelete() {
|
||||
CascadingOneManyParent parent = new CascadingOneManyParent();
|
||||
parent.setName("parent");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
CascadingOneManyChild child = new CascadingOneManyChild();
|
||||
child.setName("child" + i);
|
||||
parent.addChild(child);
|
||||
}
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.persist(parent);
|
||||
em.getTransaction().commit();
|
||||
long id = parent.getId();
|
||||
em.close();
|
||||
|
||||
em = emf.createEntityManager();
|
||||
parent = em.find(CascadingOneManyParent.class, id);
|
||||
assertNotNull(parent);
|
||||
assertEquals(2, parent.getChildren().size());
|
||||
em.getTransaction().begin();
|
||||
em.remove(parent);
|
||||
em.getTransaction().commit();
|
||||
assertRemoved(em, id);
|
||||
em.close();
|
||||
|
||||
em = emf.createEntityManager();
|
||||
assertRemoved(em, id);
|
||||
em.close();
|
||||
}
|
||||
|
||||
private void assertRemoved(EntityManager em, long id) {
|
||||
assertNull(em.find(CascadingOneManyParent.class, id));
|
||||
List res = em.createQuery("select c from CascadingOneManyChild c").
|
||||
getResultList();
|
||||
assertEquals(0, res.size());
|
||||
}
|
||||
|
||||
public void testForeignKey() {
|
||||
JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
|
||||
if (!conf.getDBDictionaryInstance().supportsForeignKeys)
|
||||
return;
|
||||
|
||||
CascadingOneManyParent parent = new CascadingOneManyParent();
|
||||
parent.setName("parent");
|
||||
CascadingOneManyChild child;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
child = new CascadingOneManyChild();
|
||||
child.setName("child" + i);
|
||||
parent.addChild(child);
|
||||
}
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.persist(parent);
|
||||
em.getTransaction().commit();
|
||||
long id = parent.getId();
|
||||
em.close();
|
||||
|
||||
OpenJPAEntityManager oem = (OpenJPAEntityManager) emf.
|
||||
createEntityManager();
|
||||
parent = oem.find(CascadingOneManyParent.class, id);
|
||||
assertNotNull(parent);
|
||||
assertEquals(2, parent.getChildren().size());
|
||||
child = parent.getChildren().get(0);
|
||||
oem.getTransaction().begin();
|
||||
oem.remove(parent);
|
||||
// undelete one child
|
||||
assertTrue(oem.isRemoved(child));
|
||||
oem.persist(child);
|
||||
assertFalse(oem.isRemoved(child));
|
||||
assertEquals(parent, child.getParent());
|
||||
try {
|
||||
oem.getTransaction().commit();
|
||||
fail("Commit should have failed due to FK constraint violation.");
|
||||
} catch (Exception e) {
|
||||
}
|
||||
oem.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(TestCascadingOneManyWithForeignKey.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -112,8 +112,9 @@ public class EntityManagerFactoryImpl
|
|||
_factory.lock();
|
||||
try {
|
||||
if (_queryCache == null)
|
||||
_queryCache = new QueryResultCacheImpl(_factory.getConfiguration().
|
||||
getDataCacheManagerInstance().getSystemQueryCache());
|
||||
_queryCache = new QueryResultCacheImpl(_factory.
|
||||
getConfiguration().getDataCacheManagerInstance().
|
||||
getSystemQueryCache());
|
||||
return _queryCache;
|
||||
} finally {
|
||||
_factory.unlock();
|
||||
|
|
Loading…
Reference in New Issue