2

JPAでの関係の管理について少し混乱しています。基本的に、1対多の関係を持つ2つのエンティティがあります

構成には、1 つまたは複数のメーリング リストを関連付けることができます。

@Entity
public class Config {
    @OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private List<Email> emailReceivers;
}
@Entity
public class Email {
    @ManyToOne
    private Config owner;
}

EJB で、構成に関連付けられた電子メールのリストを編集する更新/マージ操作中に、電子メール エンティティで削除操作を明示的に呼び出す必要はなく、電子メールを削除することで関係を管理するだけでよいと考えました。私の設定メールリスト。

@Stateless
public class ConfigFacadeImpl implements ConfigFacade{
    @EJB
    private ConfigDao configDao;
    @EJB
    private EmailDao emailDao;

    @Override
    public void update(Config Config, List<Email> emailsForDelete) {
        if(emailsForDelete!=null && emailsForDelete.size() > 0){
            for(Email emailTemp: emailsForDelete){
                Email email = emailDao.find(emailTemp.getId());
                emailDao.delete(email);  // Do I need to explicitly call the remove??
                config.getEmailReceivers().remove(email);
            }
        }
        configDao.update(config);
    }
}

削除を実行せずにリストから削除するだけでは、テーブルの行は消去されません。

削除した電子メールが UI に表示されないため、UI とデータベースは同期していませんが、データベースを確認すると、行はまだ存在しています。

必須ですか?エンティティで削除するだけで、JPAがこれを処理してくれると思いました。

アップデート

変更を加える前にデータベースからエンティティを取得するようにコードを微調整しましたが、それでも子の電子メール エンティティは削除されません。これはApacheダービーの問題なのだろうか。(エンティティを JSF マネージド Bean から EJB に渡しているため、これは正しい方法です。そのため、最初に DB から同期を取得する必要があります。)

@Override
public void update(Config config, List<Email> emailsForDelete) {
    Config configTemp = configDao.find(config.getId());
    if(emailsForDelete!=null && emailsForDelete.size() > 0){
        for(Email emailTemp: emailsForDelete){
            configTemp.getEmailReceivers().remove(emailTemp);
        }
    }
    configDao.update(config);
}
4

3 に答える 3

1

JPA 2.0 では、親エンティティで orphanRemoval=true オプションを使用できます。

例:

@Entity
public class Parent {
    ...

    @OneToMany(mappedBy="parentId",cascade=CascadeType.ALL, orphanRemoval=true)
    private List<Child> childList;
    ...

}
于 2015-12-09T22:51:40.423 に答える
1

すでに cascade type = を定義しているためCascadeType.ALL、JPA が削除を処理する必要があります。Explicit Delete記載は不要です

次の 2 つのステートメントは必須ではありません。

     Email email = emailDao.find(emailTemp.getId());
     emailDao.delete(email);  // Do I need to explicitly call the remove??

代わりに、一致するものを見つけて、行っているように一致するものを削除したい場合がemailReceiverありconfig.getEmailReceivers()ますEmailReceiversEmailデータベースからエンティティをロードする必要はありません。

編集: 孤立したオブジェクトを削除するには、CascadeType.DELETE_ORPHANカスケード属性をCascadeType.ALL.

于 2012-10-31T02:52:47.253 に答える
1

これは、 1 対多の関係でマージがカスケードされない理由と同じ問題です。

基本的に、JPA はコレクション内のエンティティのみをカスケードできます。そのため、コレクションから削除された子オブジェクトへの変更はコンテキストに入れられないため、データベースにプッシュすることはできません。この場合、oneToMany は manytones バック ポインターによって制御されるため、子もマージされない限り、コレクションの変更でさえ表示されません。子がツリーからプルーニングされると、変更を取得するために個別に管理およびマージする必要があります。

于 2012-10-31T12:45:12.390 に答える