OpenJPA:级联删除问题

时间:2016-05-25 13:53:34

标签: java db2 openjpa

我有以下实体:

//Parent
@Entity
@Table(name = "PARENT")
public class Parent  implements Serializable { 
private static final long serialVersionUID = 1L;

@Id
@Column(name = "PRIMARY_ID", updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer primaryID;

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, targetEntity = Child.class)
private List<Child> child;

//Child

@Entity
@Table(name = "CHILD")
public class Child  implements Serializable {

private static final long serialVersionUID = 1L;

@EmbeddedId
private ChildPK id;

@MapsId("primaryID") //Maps to primaryID in ChildPK
@ManyToOne
@JoinColumn(name = "PRIMARY_ID",nullable=false)
private Parent parent;

public Child() {
}

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

<persistence-unit name="jpa-test" transaction-type="RESOURCE_LOCAL">
        <properties>
            <property name="openjpa.ConnectionDriverName" value="com.ibm.db2.jcc.DB2Driver" />
            <property name="openjpa.ConnectionURL"
                value="jdbc:db2://host:port/dbname;" />
            <property name="openjpa.ConnectionUserName" value="*****" />
            <property name="openjpa.ConnectionPassword" value="*****" />
            <property name="openjpa.jdbc.Schema" value="XXXXX" />
            <property name="openjpa.jdbc.DBDictionary" value="db2" />
            <property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
            <property name="openjpa.jdbc.MappingDefaults"
                value="jpa(ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict)" />
            <property name="openjpa.Compatibility" value="StrictIdentityValues=true" />
            <property name="openjpa.Log"
                value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />
        </properties>
    </persistence-unit>
</persistence>

我试图通过对父进行删除操作来从数据库中删除记录。请在下面找到相同的代码段。

public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa-test");
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        Parent parent = entityManager.find(Parent.class, 15149);
        entityManager.getTransaction().begin();
        entityManager.remove(parent);
        entityManager.getTransaction().commit();
}

我遇到异常。请在下面找到堆栈跟踪:

Exception in thread "main" <openjpa-2.2.3-SNAPSHOT-r422266:1715851 fatal store error> org.apache.openjpa.persistence.RollbackException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
FailedObject: com.entity.test.Parent-15149
    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:594)
    at com.test.Test.main(Test.java:76)
Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1715851 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
FailedObject: com.entity.test.Parent-15149
    at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2352)
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2189)
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2087)
    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2005)
    at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
    at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1529)
    at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:933)
    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:570)
    ... 1 more
Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1715851 fatal general error> org.apache.openjpa.persistence.PersistenceException: THE RELATIONSHIP R_CNRLPH RESTRICTS THE DELETION OF ROW WITH RID X'000001271B' {prepstmnt 636888566 DELETE FROM XXXXX.PARENT WHERE PRIMARY_ID = ? [params=?]} [code=-532, state=23504]SQLCA OUTPUT[Errp=DSNXRSDL, Errd=-190, 13172769, 0, 13228485, -742129664, 0]
THE RELATIONSHIP R_CNRLPH RESTRICTS THE DELETION OF ROW WITH RID X'000001271B'
FailedObject: com.entity.test.Parent-15149
    at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4991)
    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4957)
    at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:571)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:136)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:78)
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushBatch(BatchingPreparedStatementManagerImpl.java:221)
    at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:63)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:105)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:78)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:732)
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131)
    ... 8 more
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: THE RELATIONSHIP R_CNRLPH RESTRICTS THE DELETION OF ROW WITH RID X'000001271B' {prepstmnt 636888566 DELETE FROM XXXXX.PARENT WHERE PRIMARY_ID = ? [params=?]} [code=-532, state=23504]
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:219)
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:195)
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$1000(LoggingConnectionDecorator.java:59)
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:1134)
    at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:275)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1792)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.executeUpdate(PreparedStatementManagerImpl.java:268)
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushSingleRow(BatchingPreparedStatementManagerImpl.java:250)
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushBatch(BatchingPreparedStatementManagerImpl.java:153)
    ... 13 more

sql执行的顺序是错误的。父级的删除sql在child之前执行。

目前我通过在父母之前调用对孩子的删除操作来解决这个问题。他们可以通过调用父母的删除操作来删除子记录。

0 个答案:

没有答案