2017-12-30 60 views
0

Springブートアプリケーションのaggregate-rootからイベントを発行する際に問題があります。私が基本的に望むのは、人に関するいくつかの情報が変更されるたびに「更新」イベントを公開することです。 このためのコードは非常に簡単です:Springデータドメインのイベントがなくなる(?)

@Entity 
public class Person { 
    @Transient 
    private final Collection<AbstractPersonRelatedEvent> events = new ArrayList<>(); 

    Person(Person other) { 
    // copy other fields 
    other.events.foreach(events::add); 
    } 

    // other stuff 

    public Person updateInformation(...) { 
    Person updated = new Person(this); 

    // setting new data on the updated person 

    if (!hasUpdateEventRegistered()) { 
     updated.registerEvent(PersonDataUpdatedEvent.forPerson(updated)); 
    } 
    return updated; 
    } 

    void registerEvent(AbstractPersonRelatedEvent event) { 
    events.add(event); 
    } 

    @DomainEvents 
    Collection<AbstractPersonRelatedEvent> getModificationEvents() { 
    return Collections.unmodifiableCollection(events); 
    } 

    @AfterDomainEventPublication 
    void clearEvents() { 
    events.clear(); 
    } 
} 

私はマネージャーを通じてPersonインスタンスを管理しています:私はマネージャーを呼び出すとき

@Service 
@Transactional 
class PersistentPersonManager implements PersonManager { 

// other methods are omitted 

    @Override 
    public Person save(Person person) { 
    return personRepository.save(person); 
    } 

} 

は、しかし(manager.save(person.updateInformation(...))のイベントは、「行方不明」に行くように見える: save()メソッドを呼び出すと、すべてのイベントがまだ存在しますが、SpringがgetModificationEvents()を呼び出すと、コレクションは空です。イベントは、その間のどこかで消滅したように見えます(Springコードのみが実行されています)。

これはかなり基本的なものなので、私は本質的なものを逃してしまっているに違いありません。

ここで私はどのようにして戻ってきますか?

答えて

1

ここでJPAを使用していると仮定します。

JPAについては、save操作は実際にJPA EnityManagermergeを実行します。

デタッチされたエンティティの場合mergeは、データベースまたは現在のセッションから同じIDを持つエンティティをロード/検出し、すべての(変更された)フィールドをコピーします。これは、イベントのような一時的なフィールドを無視します。

updateInformationを呼び出すたびに新しいエンティティを作成するため、分離エンティティを扱っています。だからここ

は何が起こっているかである。

  1. あなたは、データベースからのエンティティ(E1)をロードします。イベントは登録されていません。

  2. updateInformationを呼び出すと、新しいデタッチエンティティ(e2)が作成されます。あなたはまた、e2でイベントを登録します。

  3. save JPAを呼び出してイベントを除くことにE2からのすべての変更、一致E1およびコピーを見つけました。したがってe1にはまだイベントが登録されていません。

  4. イベントはトリガーされますが、e1のみが使用されるため、イベントは発生しません。

これを修正するには:updateInformationにエンティティの新しいインスタンスを作成しないでください。

関連する問題