0

私は現在、次のような設定をしています:

@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
    private Long id;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

@Entity
public class Container extends AbstractEntity {
    private Collection<Item> items = new HashSet<>();

    @Cascade(CascadeType.SAVE_UPDATE)
    @OneToMany(mappedBy = "container", orphanRemoval = true)
    public Collection<Item> getItems() { return items; }

    public void setItems(Collection<Item> items) { this.items = items; }
}

@Entity
public class Item extends AbstractEntity {
    private Container container;

    @ManyToOne(optional = false)
    public Container getContainer() { return container; }

    public void setContainer(Container container) { this.container = container; }
}

@Entity
public class FirstItemDetails extends AbstractEntity {
    private Item item;

    @OneToOne(optional = false)
    @Cascade({CascadeType.DELETE, CascadeType.REMOVE})
    public Item getItem() { return item; }

    public void setItem(Item item) { this.item = item; }
}

@Entity
public class SecondItemDetails extends AbstractEntity {
    private Item item;

    @OneToOne(optional = false)
    @Cascade({CascadeType.DELETE, CascadeType.REMOVE})
    public Item getItem() { return item; }

    public void setItem(Item item) { this.item = item; }
}

最終的には違いがないので、不要なフィールドのいくつかを省略しました。さて、問題です。私がやりたいことは次のようなものです:

public void removeItemFromContainer(Item item, Container container) {
    Transaction transaction = session.beginTransaction();
    container.getItems().remove(item);
    session.save(container);
    transaction.commit();
}

この関数に期待するのは、特定のコンテナーからアイテムを物理的に削除することです。 orphanRemovalをtrueに設定しているため、コンテナーを永続化すると、実際にデータベースからアイテムを削除しようとします。ここでの問題は、 foreign_key 制約を持つItemDetails エンティティにあるため、コミットが実行されているときに次のようになります。

org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no action; FK_FITEM_DETAILS_ITEM table: first_item_details
Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_FITEM_DETAILS_ITEM table: first_item_details

私にとって最も紛らわしい部分は、休止状態に依存してカスケードするのではなく、データベースのfirst_item_detailsテーブルにON DELETE CASCADEを物理的に追加すると、すべてが機能することです。しかし、このアプローチはエラーが発生しやすいため、ある時点で詳細エンティティのいずれかにインターセプターまたはeventListenerを使用することを決定した場合、単に機能しないため、休止状態にする必要があるのではなく、それを処理できるようにすることをお勧めします。手動のデータベース構造の変更に依存します。

4

1 に答える 1