简体   繁体   English

Spring Data Domain事件丢失(?)

[英]Spring Data domain events go missing (?)

I am having trouble publishing events from an aggregate-root in a Spring Boot application. 我在Spring Boot应用程序中从聚合根发布事件时遇到麻烦。 What I basically want is to publish an "Update" event every time some information about a person is changed. 我基本上想要的是每次有关某个人的某些信息更改时都发布“更新”事件。 The code for this is pretty straightforward: 此代码非常简单:

@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();
  }
}

I am managing Person instances through a manager: 我正在通过经理来管理Person实例:

@Service
@Transactional
class PersistentPersonManager implements PersonManager {

 // other methods are omitted

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

}

However when I call the manager ( manager.save(person.updateInformation(...)) the events seem to go "missing": upon calling the save() method all events are still present but when Spring invokes getModificationEvents() the collection is empty. The events seem to have vanished somewhere in between (with only Spring-code being executed). 但是,当我调用管理器( manager.save(person.updateInformation(...)) ,事件似乎“丢失”了:调用save()方法时,所有事件仍然存在,但是当Spring调用getModificationEvents() ,集合事件为空(仅执行Spring代码)。

As this is pretty basic, I must be missing something essential but got stuck in a rut. 因为这是非常基本的,所以我必须错过一些必不可少的东西,但会陷入困境。

So how do I get back on track here? 那么如何在这里重回正轨?

I assume you are using JPA here. 我假设您在这里使用JPA。

For JPA the save operation actually does a merge on the JPA EnityManager . 对于JPA, save操作实际上是在JPA EnityManager上进行merge

For a detached entity merge loads/finds the entity with the same id from the database or the current session and copies all the (changed) fields over. 对于分离的实体, merge将从数据库或当前会话中加载/查找具有相同ID的实体,然后复制所有(更改的)字段。 This does ignore transient fields like the events. 这确实会忽略瞬态字段,例如事件。

You are dealing with detached entities because you are creating a new entity every time you call updateInformation . 您正在处理分离的实体,因为每次调用updateInformation时都在创建一个新实体。

So here is what is happening: 所以这是正在发生的事情:

  1. You load an entity ( e1 ) from the database. 您从数据库中加载实体( e1 )。 It does not have any events registered. 它没有注册任何事件。

  2. By calling updateInformation you create a new detached entity ( e2 ). 通过调用updateInformation您可以创建一个新的分离实体( e2 )。 You also register events with e2 . 您还可以向e2注册事件。

  3. When calling save JPA finds the matching e1 and copies all changes from e2 into it, except the events. 调用save JPA将找到匹配的e1并将所有更改从e2复制到其中,事件除外。 So e1 still has no events registered. 因此, e1仍未注册任何事件。

  4. Events get triggered, but there aren't any because only e1 is used. 事件被触发,但是没有任何事件,因为仅使用了e1

In order to fix this: Do not create new instances of the entity in updateInformation . 为了解决此问题:不要在updateInformation创建实体的新实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM