Реализация моментального снимка в AXON 3.0: тип агрегата неизвестен в этом снимке

Я все еще новичок в работе с аксоном.

Я пытаюсь реализовать снимок с помощью mongodb в моем приложении, и я получаю сообщение об ошибке

"AbstractSnapshotter: попытка создать и сохранить моментальный снимок привела к исключению. Сводка исключений: Совокупный тип неизвестен в этом снимке: com.myworklife.contacts.domain.contact.Contact"

Это часть моего файла конфигурации Java.

@Bean
public AggregateSnapshotter snapShotter(EventStore eventStore, AggregateFactory<Contact> contactAggregateFactory) {
    return new AggregateSnapshotter(eventStore);
}


@Bean
public SnapshotTriggerDefinition snapshotTriggerDefinition(Snapshotter snapShotter) throws Exception {
    return new EventCountSnapshotTriggerDefinition(snapShotter, 1);
}

@Bean
public EventStore eventStore(EventStorageEngine eventStorageEngine)  {
    return new EmbeddedEventStore(eventStorageEngine);
}

@Bean
public Repository<Contact> contactAggregateRepository(EventStore eventStore, SnapshotTriggerDefinition snapshotTriggerDefinition) {
    return new ContactRepository(eventStore, snapshotTriggerDefinition);
}

И мой репозиторий.

    @Repository("ContactRepository")
public class ContactRepository extends EventSourcingRepository<Contact> {

    @Autowired
    public ContactRepository(EventStore eventStore, SnapshotTriggerDefinition snapshotTriggerDefinition) {
        super(Contact.class, eventStore, snapshotTriggerDefinition);
    }

    public Contact findContact(ContactId contactId) {
        return load(contactId.toString()).getWrappedAggregate().getAggregateRoot();
    }
}

Моя совокупность.

@Aggregate(repository="contactAggregateRepository")
public class Contact {

    @AggregateIdentifier
    private ContactId id;
    private String name;
    private String mobileNumber;

    public Contact() {
        // do nothing, Axon requires default constructor
    }

    @CommandHandler
    public Contact(CreateContactCommand createContactCommand) {
        apply(new ContactHasBeenCreatedEvent(createContactCommand.getContactId(), createContactCommand.getName(),
                createContactCommand.getMobileNumber()));
    }
}

Я что-то не так делаю?

так как я получаю сообщение об ошибке "При попытке создать и сохранить моментальный снимок возникла исключительная ситуация. Сводка исключений: Агрегатный тип неизвестен в этом снимке: com.myworklife.contacts.domain.contact.Contact"

Любая помощь будет высоко оценена.

Спасибо пэт

2 ответа

Вам нужно добавить contactAggregateFactory в конструктор AggregateSnapshotter в bean-компоненте snapShotter:

@Bean
public AggregateSnapshotter snapShotter(EventStore eventStore,    AggregateFactory<Contact> contactAggregateFactory) {
    return new AggregateSnapshotter(eventStore, contactAggregateFactory);
}

Баночка 1.depencity

 <dependency>
    <groupId>org.axonframework</groupId>
    <artifactId>axon-spring-boot-autoconfigure</artifactId>
    <version>${axon.version}</version>
</dependency>

2. Сначала вы должны настроить ваш application.ymp или bootstrap.yml, например так:spring: data: mongodb: host: localhost port: 27017 database: axonframework events: domainevents snapshots: snapshotevents

3. Настройте ваш mongoDB:

    @Bean(name = "axonMongoTemplate")
public MongoTemplate axonMongoTemplate() {
    MongoTemplate template = new DefaultMongoTemplate(mongoClient(), mongoDbName, eventsCollectionName, snapshotCollectionName);
    return template;
}

@Bean
public MongoClient mongoClient(){
    MongoFactory mongoFactory = new MongoFactory();
    mongoFactory.setMongoAddresses(Arrays.asList(new ServerAddress(mongoHost)));
    return mongoFactory.createMongo();
}

@Bean
public EventStorageEngine eventStorageEngine(Serializer serializer){
    return new MongoEventStorageEngine(
            serializer,null, axonMongoTemplate(), new DocumentPerEventStorageStrategy());

4.config хранилище для вашего агрегата, например, я настраиваю хранилище Element Aggreaget

@Configuration
public class ElementConfiguration {

    @Autowired
    private EventStore eventStore;
    @Bean
    @Scope("prototype")
    public Element elementAggregate() {
        return new Element();
    }

    @Bean
    public AggregateFactory<Element> elementAggregateAggregateFactory() {

        SpringPrototypeAggregateFactory<Element> aggregateFactory = new SpringPrototypeAggregateFactory<>();
        aggregateFactory.setPrototypeBeanName("elementAggregate");
        return aggregateFactory;
    }
    @Bean
    public SpringAggregateSnapshotterFactoryBean springAggregateSnapshotterFactoryBean(){

        SpringAggregateSnapshotterFactoryBean factory = new SpringAggregateSnapshotterFactoryBean();
        return factory;
    }
     @Bean
    public Repository<Element> elementAggregateRepository(Snapshotter snapshotter) {

        EventCountSnapshotTriggerDefinition eventCountSnapshotTriggerDefinition = new EventCountSnapshotTriggerDefinition(snapshotter, 3);


        EventSourcingRepository<Element> repository = new EventSourcingRepository<Element>(
            elementAggregateAggregateFactory(),
            eventStore,
            eventCountSnapshotTriggerDefinition
        );
        return repository;
    }

5.enjoy

Если вы используете Axon 3.3 и SpringBoot 2, вот как мы это сделали в этом проекте:

@Configuration
public class SnapshotConfiguration {

    @Bean
    public SpringAggregateSnapshotter snapshotter(ParameterResolverFactory parameterResolverFactory,
                                                  EventStore eventStore,
                                                  TransactionManager transactionManager) {
        // https://docs.axoniq.io/reference-guide/v/3.3/part-iii-infrastructure-components/repository-and-event-store#snapshotting
        // (...) By default, snapshots are created in the thread that calls the scheduleSnapshot() method, which is generally not recommended for production (...)
        Executor executor = Executors.newSingleThreadExecutor();
        return new SpringAggregateSnapshotter(eventStore, parameterResolverFactory, executor, transactionManager);
    }

    @Bean
    public EventCountSnapshotTriggerDefinition snapshotTrigger(SpringAggregateSnapshotter snapshotter) {
        int snapshotThreshold = 42;
        return new EventCountSnapshotTriggerDefinition(snapshotter, snapshotThreshold);
    }
}

И если вам нужна конфигурация EventStore:

@Configuration
public class AxonMongoEventStoreConfiguration {

    @Bean
    public MongoClient axonMongoClient(MongoClientURI axonMongoClientUri) {
        return new MongoClient(axonMongoClientUri);
    }

    @Bean
    public MongoClientURI axonMongoClientUri() {
        return new MongoClientURI("mongodb://host:port/database");
    }

    @Bean
    @Primary
    public EventStorageEngine eventStore(MongoClient axonMongoClient, MongoClientURI axonMongoClientUri) {
        DefaultMongoTemplate mongoTemplate = new DefaultMongoTemplate(axonMongoClient, axonMongoClientUri.getDatabase());
        return new MongoEventStorageEngine(mongoTemplate);
    }
}
Другие вопросы по тегам