Как вы заметили, Axon принудительно введет String
для совокупного идентификатора. Это не значит, что вам нужно предоставить String
напрямую. Он будет отлично работать, если у вас есть разумный метод toString()
. Следовательно, использование Integer
в качестве идентификатора агрегата приведет к результату toString()
этого поля, которое будет использоваться в качестве идентификатора агрегата.
Сказав это, я удивлен, что вы не можете загрузить агрегат основываясь на этом. Может быть, нам нужно предпринять некоторые действия, основываясь на этом, но сначала я хочу прокомментировать сниппет, которым вы делитесь.
Кажется, у вас есть обработчик команды конструктора для класса Order
. Более того, это сигнализирует мне, что класс Order
является агрегатом. Я хотел бы заявить, что никоим образом я бы никогда не рекомендовал загружать в Агрегат из другого Агрегата.
При этом связывается блокировка в агрегате Order
с Product
агрегат, таким образом блокируя большую часть вашей системы, чем мог бы ожидать отправитель CreateOrderCommand
. Связь между агрегатами должна всегда поддерживаться асинхронной посредством сообщений о событиях. Таким образом, для этого требуется выделенный компонент обработки событий, который координирует оба экземпляра на основе опубликованного события.
Поэтому я настоятельно рекомендую переписать вашу логику c по данному вопросу. Когда дело доходит до загрузки в совокупности, мне будет сложно дать вам обоснование прямо сейчас. Поэтому позвольте мне задать пару последующих вопросов. Я бы посоветовал дополнить ваш оригинальный запрос ответами; для поддержания хорошей непрерывности.
Какую версию Axon вы используете каким-либо образом? Используете ли вы какие-либо интересные конфигурации вокруг совокупности Product
? Вы связываете свое приложение с Axon Server? Если это так, стандарт или предприятие, и какая версия? Вы используете API конфигурации напрямую или axon-spring-boot-starter
?
Обновление
Спасибо за обновление вашего вопроса, Киндсон, позвольте мне обновить мой ответ тоже.
Во-первых, как я уже говорил ранее, я бы никогда не загружал бы в Агрегат из другого Агрегата. И ваш класс Order
, и класс Product
являются агрегатами, и фрагменты дают слишком четкое представление о том, что вы консолидируете «продукт Repository
» из агрегата Order
.
Этот подход не только продлевает блокирует ваши агрегаты, что создает нагрузку на ваших пользователей, но при таком подходе могут возникнуть тупики. Как правило, всегда следуют асинхронному подходу к взаимодействию между агрегатными экземплярами. Таким образом, компонент реагирует на события агрегата и отправляет команды другому. Это можно сделать с помощью обычного компонента обработки событий или, например, саги.
Помимо вышесказанного, я локально проверил, могу ли я использовать Integer
в качестве совокупного идентификатора. Таким образом, как аннотированное поле @AggregateIdentifier
в совокупности и как аннотированное поле @TargetAggregateIdentifier
в вашем командном сообщении. Вдобавок ко всему, я попробовал это, заставив фреймворк вызвать операцию Repository#load(String)
(таким образом, просто отправив команду на CommandGateway
/ CommandBus
) и , вызвав ее напрямую, как вы это сделали.
К сожалению, у меня все хорошо. Таким образом, в качестве другого продолжения, я бы предложил поделиться фактическим исключением, которое вы получаете, когда выполняете операцию Repository#load(String)
.