Axon 服务器命令不包含路由键

Axon Server Command does not contain routing key

我正在尝试使用 Axon 服务器将我的应用程序迁移到 Axon 4.0。 这是我的代码。

data class CreateTravelProductCommand(
    @TargetAggregateIdentifier val id: String,
    val productCreator: String
)

val id: String = ObjectId.get().toString()
val command = CreateTravelProductCommand(id=id, productCreator=request.creator)
commandGateway.sendAndWait(command)

但是我的命令出现了这个错误。

org.axonframework.commandhandling.distributed.CommandDispatchException: The command [com.sunday.api.product.CreateTravelProductCommand] does not contain a routing key. at org.axonframework.commandhandling.distributed.AbstractRoutingStrategy.getRoutingKey(AbstractRoutingStrategy.java:57) ~[axon-messaging-4.0.jar:4.0] at org.axonframework.axonserver.connector.command.AxonServerCommandBus.dispatch(AxonServerCommandBus.java:114) ~[axon-server-connector-4.0.jar:4.0] at org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:75) [axon-messaging-4.0.jar:4.0] at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:78) [axon-messaging-4.0.jar:4.0] at org.axonframework.commandhandling.gateway.DefaultCommandGateway.sendAndWait(DefaultCommandGateway.java:96) [axon-messaging-4.0.jar:4.0] at com.sunday.underwriting.product.ProductHandler.sendCreateProductCommand(ProductHandler.kt:40) [classes/:na] at com.sunday.underwriting.product.ProductHandler.access$sendCreateProductCommand(ProductHandler.kt:33) [classes/:na] at com.sunday.underwriting.product.ProductHandler$createProduct$product.invoke(ProductHandler.kt:97) [classes/:na] at com.sunday.underwriting.product.ProductHandler$createProduct$product.invoke(ProductHandler.kt:33) [classes/:na] at com.sunday.underwriting.product.ProductHandler$sam$java_util_function_Function[=12=].apply(ProductHandler.kt) [classes/:na] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1476) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:794) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:560) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:540) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:426) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.DrainUtils.postCompleteDrain(DrainUtils.java:131) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.DrainUtils.postComplete(DrainUtils.java:186) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxMapSignal$FluxMapSignalSubscriber.onComplete(FluxMapSignal.java:213) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:378) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:202) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:343) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:325) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:442) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:141) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:188) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) [netty-codec-4.1.29.Final.jar:4.1.29.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) [netty-codec-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:563) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [netty-transport-4.1.29.Final.jar:4.1.29.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:884) [netty-common-4.1.29.Final.jar:4.1.29.Final] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]

编辑:

我刚发现,如果你把 class 放在同一个项目中,就可以了。

问题是当您从另一个项目(在 axon 服务器之前工作)导入 class

例如:

我的项目依赖于另一个名为 api 的项目。

dependencies {
    compile project(':api')
}

如果在 api 项目中声明了 class,axon 服务器库将抛出找不到路由键的错误。但是如果 class 在它自己的主项目中声明,它会按预期工作。我想我应该在 github.

上提交这个问题

这实际上与 Kotlin 的关系比与 Axon 的关系更大。 Axon 在 Field 或 Getter 方法上期望它们。显然,这不是 Kotlin 将它们设置为默认值的地方。

查看https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets

您可能需要用 @get:TargetAggregateIdentifier

注释 属性

真正的问题是两个项目之间的版本不匹配。我必须更正版本,但 intellij 自动加载器无法正常工作,api 项目的版本不正确。

我为我的愚蠢道歉

我在从 Axon 3.x 迁移到 4.0 时遇到了同样的问题。 该解决方案与 @TargetAggregateIdentifier 有关 - 我在我的聚合处理的 'CreateXXXCommand' 中遗漏了它。我很确定在 Axon 3.x

中创建命令不需要添加 @TargetAggregateIdentifier(因为它不必定位现有聚合)

撰写本文时迁移指南不完整https://docs.axoniq.io/reference-guide/3-migration/migration-guide