gpt4 book ai didi

java - Spring Data 域事件丢失(?)

转载 作者:行者123 更新时间:2023-12-02 02:24:13 25 4
gpt4 key购买 nike

我在从 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 从数据库或当前 session 中加载/查找具有相同 id 的实体,并复制所有(已更改)字段。这确实忽略了像事件这样的 transient 字段。

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

所以这就是发生的事情:

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

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

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

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

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

关于java - Spring Data 域事件丢失(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48035815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com