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:
A. Abram White 2006-09-11 23:54:01 +00:00
parent f56a7555a7
commit 1e95734015
10 changed files with 299 additions and 16 deletions

View File

@ -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)

View File

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

View File

@ -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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();