1

私は Eclipselink を使用しており、削除の問題に直面しています。ManyToOne以下のように参加しました。

public class UserEntity implements Serializable {
...
@ManyToOne
@JoinColumn(name = "STUDENT_CD", nullable=false)
private StudentEntity student;
}

を削除しようとするとUserEntity、以下の例外が発生します。

[#|2013-08-07T20:44:52.105+0530|WARNING|glassfish3.1.2|javax.enterprise.resource.jta.com.sun.enterprise.transaction|_ThreadID=35;_ThreadName=Thread-2;|DTX5014: Caught exception in beforeCompletion() callback:
Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-01407: cannot update ("SERVICE"."USERS"."STUDENT_CD") to NULL

Error Code: 1407
Call: UPDATE SERVICE.USERS SET STUDENT_CD = ? WHERE (USER_ID = ?)
    bind => [null, 1]

    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.updateObject(DatasourceCallQueryMechanism.java:749)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.updateObject(StatementQueryMechanism.java:432)
    at org.eclipse.persistence.internal.queries.CallQueryMechanism.updateForeignKeyFieldBeforeDelete(CallQueryMechanism.java:436)

ここではバグとして言及されています。 https://bugs.eclipse.org/bugs/show_bug.cgi?format=multiple&id=341709

この問題は、Eclipselink 2.4 で発生します。

助言がありますか?

アップデート

@Entity
@Table(name = "USER", schema="SERVICE")
public class UserEntity implements Serializable {
...
// bi-directional many-to-one association to StudentEntity
@ManyToOne
@JoinColumn(name = "STUDENT_CD", nullable=false)
private StudentEntity student;
...
}

@Entity
@Table(name = "STUDENT", schema="SERVICE")
public class StudentEntity implements Serializable {
...
@Id
@Column(name = "STUDENT_CD")
private String studentCd;

@OneToMany(mappedBy = "student")
private Set<UserEntity> users;
...
}

私はJPAが初めてです。私の理解では、サイクルはありません。

4

1 に答える 1

0

すべての関係を含む完全なクラス マッピングと、完全な SQL トレースを含めてください。

EclipseLink は、循環を検出すると、削除中に外部キーのみを null にします。つまり、外部キーを介して相互に参照する 2 つ以上のオブジェクトを削除しようとしています。いずれかの側から削除すると外部キー制約違反が発生するため、技術的にはこのモデルを削除する方法はありません。

双方向の外部キー依存関係を持たないようにモデルを再考することをお勧めします。通常、双方向の関係がある場合、片側で「mappedBy」を使用するため、両方の関係に 1 つの外部キーのみが使用されます。

サイクルがあり、null でない制約がある場合、データを削除できなくしている可能性がありますが、これはおそらく悪い考えです。制約の 1 つを緩和する必要があります。外部キーの 1 つが null ではなく、1 つが null 可能である場合は、オブジェクトを削除する前に null 可能のものを自分で null に設定して、循環を回避できます。また、constraintDependency を使用して、EclipseLink の null の側に影響を与えることもできます。

非 null 制約を考慮した 2.5.2 リリースを試すこともできます。

于 2013-08-08T13:39:52.877 に答える