mirror of https://github.com/apache/openjpa.git
OPENJPA-235 SQL reordering to avoid non-nullable foreign key constraint violations
Fix problem in deletion for foreign key on delete cascade. Commit openjpa-235-delete-cascade.patch provided by Fay Wang. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@673258 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1aa44030d6
commit
de790be2ad
|
@ -256,7 +256,8 @@ public class RelationFieldStrategy
|
||||||
if (rel != null) {
|
if (rel != null) {
|
||||||
ForeignKey fk = field.getForeignKey((ClassMapping)
|
ForeignKey fk = field.getForeignKey((ClassMapping)
|
||||||
rel.getMetaData());
|
rel.getMetaData());
|
||||||
if (fk.getDeleteAction() == ForeignKey.ACTION_RESTRICT) {
|
if (fk.getDeleteAction() == ForeignKey.ACTION_RESTRICT ||
|
||||||
|
fk.getDeleteAction() == ForeignKey.ACTION_CASCADE) {
|
||||||
Row row = field.getRow(sm, store, rm, Row.ACTION_DELETE);
|
Row row = field.getRow(sm, store, rm, Row.ACTION_DELETE);
|
||||||
row.setForeignKey(fk, null, rel);
|
row.setForeignKey(fk, null, rel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,10 +192,10 @@ public class PrimaryRow
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is a delete, delay foreign keys to other deleted objects if
|
* If this is a delete, delay foreign keys to other deleted objects if the
|
||||||
* the key is restricted. If this is an update or insert, delay foreign
|
* key is restricted or cascade. If this is an update or insert, delay
|
||||||
* keys to other inserts if the key is not logical. If the foreign key
|
* foreign keys to other inserts if the key is not logical. If the foreign
|
||||||
* is to a new record and the columns are auto-inc, record it.
|
* key is to a new record and the columns are auto-inc, record it.
|
||||||
*/
|
*/
|
||||||
private boolean delayForeignKey(ForeignKey fk, OpenJPAStateManager sm,
|
private boolean delayForeignKey(ForeignKey fk, OpenJPAStateManager sm,
|
||||||
boolean set) {
|
boolean set) {
|
||||||
|
@ -204,7 +204,8 @@ public class PrimaryRow
|
||||||
|
|
||||||
if (getAction() == ACTION_DELETE)
|
if (getAction() == ACTION_DELETE)
|
||||||
return sm.isDeleted() && !fk.isDeferred()
|
return sm.isDeleted() && !fk.isDeferred()
|
||||||
&& fk.getDeleteAction() == ForeignKey.ACTION_RESTRICT;
|
&& (fk.getDeleteAction() == ForeignKey.ACTION_RESTRICT ||
|
||||||
|
fk.getDeleteAction() == ForeignKey.ACTION_CASCADE);
|
||||||
|
|
||||||
if (!sm.isNew() || sm.isFlushed())
|
if (!sm.isNew() || sm.isFlushed())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.kernel;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EntityF {
|
||||||
|
@Id private int id;
|
||||||
|
|
||||||
|
@OneToMany(cascade=CascadeType.ALL, mappedBy="entityF")
|
||||||
|
private List<EntityG> listG;
|
||||||
|
|
||||||
|
public List<EntityG> getListG() {
|
||||||
|
return listG;
|
||||||
|
}
|
||||||
|
public void setListG(List<EntityG> listG) {
|
||||||
|
this.listG = listG;
|
||||||
|
}
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.kernel;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||||
|
import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EntityG {
|
||||||
|
@Id private int id;
|
||||||
|
|
||||||
|
@ForeignKey(deleteAction=ForeignKeyAction.CASCADE)
|
||||||
|
@ManyToOne (cascade=CascadeType.MERGE)
|
||||||
|
private EntityF entityF;
|
||||||
|
|
||||||
|
public EntityF getEntityF() {
|
||||||
|
return entityF;
|
||||||
|
}
|
||||||
|
public void setEntityF(EntityF entityF) {
|
||||||
|
this.entityF = entityF;
|
||||||
|
}
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.jdbc.kernel;
|
package org.apache.openjpa.jdbc.kernel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||||
|
@ -37,7 +39,8 @@ public class TestNoForeignKeyViolation
|
||||||
private EntityD entityD;
|
private EntityD entityD;
|
||||||
|
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
setUp(EntityA.class, EntityB.class, EntityC.class, EntityD.class, EntityE.class);
|
setUp(EntityA.class, EntityB.class, EntityC.class, EntityD.class,
|
||||||
|
EntityE.class, EntityF.class, EntityG.class);
|
||||||
|
|
||||||
createTestData();
|
createTestData();
|
||||||
}
|
}
|
||||||
|
@ -154,4 +157,55 @@ public class TestNoForeignKeyViolation
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testForeignKeyCascade() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
try {
|
||||||
|
EntityF f = new EntityF();
|
||||||
|
f.setId(1);
|
||||||
|
|
||||||
|
List<EntityG> listG = new ArrayList<EntityG>();
|
||||||
|
EntityG g1 = new EntityG();
|
||||||
|
g1.setId(1);
|
||||||
|
listG.add(g1);
|
||||||
|
g1.setEntityF(f);
|
||||||
|
|
||||||
|
EntityG g2 = new EntityG();
|
||||||
|
g2.setId(2);
|
||||||
|
listG.add(g2);
|
||||||
|
g2.setEntityF(f);
|
||||||
|
|
||||||
|
EntityG g3 = new EntityG();
|
||||||
|
g3.setId(3);
|
||||||
|
listG.add(g3);
|
||||||
|
g3.setEntityF(f);
|
||||||
|
|
||||||
|
EntityG g4 = new EntityG();
|
||||||
|
g4.setId(4);
|
||||||
|
listG.add(g4);
|
||||||
|
g4.setEntityF(f);
|
||||||
|
|
||||||
|
f.setListG(listG);
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(f);
|
||||||
|
em.persist(g1);
|
||||||
|
em.persist(g2);
|
||||||
|
em.persist(g3);
|
||||||
|
em.persist(g4);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.remove(f);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Fail to delete EntityF");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive())
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue