繁体   English   中英

Spring Data Domain事件丢失(?)

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

我在Spring Boot应用程序中从聚合根发布事件时遇到麻烦。 我基本上想要的是每次有关某个人的某些信息更改时都发布“更新”事件。 此代码非常简单:

@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代码)。

因为这是非常基本的,所以我必须错过一些必不可少的东西,但会陷入困境。

那么如何在这里重回正轨?

我假设您在这里使用JPA。

对于JPA, save操作实际上是在JPA EnityManager上进行merge

对于分离的实体, merge将从数据库或当前会话中加载/查找具有相同ID的实体,然后复制所有(更改的)字段。 这确实会忽略瞬态字段,例如事件。

您正在处理分离的实体,因为每次调用updateInformation时都在创建一个新实体。

所以这是正在发生的事情:

  1. 您从数据库中加载实体( e1 )。 它没有注册任何事件。

  2. 通过调用updateInformation您可以创建一个新的分离实体( e2 )。 您还可以向e2注册事件。

  3. 调用save JPA将找到匹配的e1并将所有更改从e2复制到其中,事件除外。 因此, e1仍未注册任何事件。

  4. 事件被触发,但是没有任何事件,因为仅使用了e1

为了解决此问题:不要在updateInformation创建实体的新实例。

暂无
暂无

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

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