3

そのため、休止状態の実装に問題があります。親クラスを削除しようとすると、カスケード階層の奥にあるクラスで外部キー制約の例外が発生します。詳細に入る前に、まずクラスの関係について説明します。これは、クラスを保存および削除する方法に関係があるためです。

最上位には、DefaultMask オブジェクトのリストを含む Customer クラスがあります。これはマスター リストです。これらのデフォルト マスクは、オブジェクト階層内の他のクラスによって使用されますが、常にこのリストから使用されます。マスクはこのリストにのみ作成され、このリストから削除されます。

階層のさらに下には、(オプションで) DefaultMask を設定できる Column クラスがあります。関係をより簡潔に説明します。

顧客はゼロから多数の DefaultMask を所有しています。顧客はゼロから多数の列を所有しています。列には 1 つの DefaultMask が含まれる場合があります。

私のアプリケーションでは、Customer を削除しようとすると、Column クラスの DefaultMask クラスに対する外部キー制約から例外が発生します。CascadeType の設定が正しくないことが問題だと思います。私は問題を調査し、mappedBy と呼ばれる属性に関する情報と、Hibernate 独自の CascadeType.SAVE_UPDATE の使用に関する情報を見つけました (Hibernate が Column によって保持されている DefaultMask を削除しようとするのを防ぐため)。いくつかの直接的なガイダンスを使用してください。クラスに関連するコードと実際の例外メッセージを以下に示します。

お客様:

@Entity
public class Customer {

@Id
private String id;
@OneToMany(cascade = CascadeType.ALL)
private List<DefaultMask> masks;
    //(Columns are held further down in hierarchy)

桁:

@Entity
@Table(name = "WarehouseColumn")
public class Column implements Comparable<Column> {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
@OneToOne
private DefaultMask mask;

デフォルトマスク:

@Entity
public class DefaultMask implements Mask {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
private String type;
private String mask;

例外メッセージ:

org.hibernate.exception.ConstraintViolationException: 親行を削除または更新できません: 外部キー制約が失敗します ( hibernate. WarehouseColumn, CONSTRAINT FK8BB153D994AD57D3FOREIGN KEY ( mask_hibernateID) REFERENCES DefaultMask( hibernateID)) 原因: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 削除できませんまたは親行を更新します: 外部キー制約が失敗します ( hibernate. WarehouseColumn, CONSTRAINT FK8BB153D994AD57D3FOREIGN KEY ( mask_hibernateID) REFERENCES DefaultMask( hibernateID))

4

2 に答える 2

1

顧客を削除しようとすると、デフォルトのマスクのリストが自動的に削除されます。ただし、これらのマスクの 1 つは列によって参照されます。そのため、データベース (および Hibernate) は削除の実行を拒否します。これは、列が一貫性のない状態のままになるためです。もう存在しないデフォルトのマスクを参照します。

したがって、いくつかの機能的な選択肢があります。

  • そのままにしておきます: マスクの 1 つがまだ列によって参照されているため、顧客を削除できません。
  • カスケードを削除します。顧客を削除すると、顧客は削除されますが、そのマスクは削除されません。
  • 削除するユーザーのデフォルト マスクのいずれかを参照するすべての列を見つけて、これらの列を削除します。次に、ユーザーとそのデフォルトのマスクを削除します
  • 削除するユーザーのデフォルト マスクのいずれかを参照するすべての列を検索し、それらのマスク フィールドを null に設定します。次に、ユーザーとそのデフォルトのマスクを削除します
于 2012-11-05T11:43:56.877 に答える
1

カスケードは、論理所有権の概念と密接に関連しています。

基本的に、次のオプションのいずれかを選択する必要があります。

  • CustomerDefaultMask論理的にそのsを所有しています。この場合DefaultMask、 を削除するときに も削除するCustomer必要があるため、 を使用する必要がありますCascadeType.ALLColumn参照しているためDefaultMask、おそらく所有者Customerも同様であり、削除する必要があります

    これは、次のように、 と の間の双方向の関係を適切なカスケードで使用することによって実現できDefaultMaskますColumn

    @Entity
    public class DefaultMask implements Mask {
        @OneToOne(mappedBy = "mask", cascade = CascadeType.ALL)
        Column column;
        ...
    }
    
  • DefaultMaskはそれ自体がエンティティであり、Customer既存DefaultMaskの を参照するだけです。この場合、おそらくこの関係にカスケードを使用する必要はまったくありません。

于 2012-11-05T11:43:26.513 に答える