mirror of https://github.com/apache/openjpa.git
OpenJPA-235: merged fix from trunk 673258, "SQL reordering to avoid non-nullable foreign key constraint violations"
git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.1.x@802195 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
eb934b2ae7
commit
5781d27887
|
@ -248,7 +248,8 @@ public class RelationFieldStrategy
|
|||
if (rel != null) {
|
||||
ForeignKey fk = field.getForeignKey((ClassMapping)
|
||||
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.setForeignKey(fk, null, rel);
|
||||
}
|
||||
|
|
|
@ -192,10 +192,10 @@ public class PrimaryRow
|
|||
}
|
||||
|
||||
/**
|
||||
* If this is a delete, delay foreign keys to other deleted objects if
|
||||
* the key is restricted. If this is an update or insert, delay foreign
|
||||
* keys to other inserts if the key is not logical. If the foreign key
|
||||
* is to a new record and the columns are auto-inc, record it.
|
||||
* If this is a delete, delay foreign keys to other deleted objects if the
|
||||
* key is restricted or cascade. If this is an update or insert, delay
|
||||
* foreign keys to other inserts if the key is not logical. If the foreign
|
||||
* key is to a new record and the columns are auto-inc, record it.
|
||||
*/
|
||||
private boolean delayForeignKey(ForeignKey fk, OpenJPAStateManager sm,
|
||||
boolean set) {
|
||||
|
@ -204,7 +204,8 @@ public class PrimaryRow
|
|||
|
||||
if (getAction() == ACTION_DELETE)
|
||||
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())
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
@ -37,7 +39,8 @@ public class TestNoForeignKeyViolation
|
|||
private EntityD entityD;
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -154,4 +157,55 @@ public class TestNoForeignKeyViolation
|
|||
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