AxonServerCommandDispatchException: The command [PlaceOrderCommand] does not contain a routing key
Definition:
class PlaceOrderCommand
data class OrderPlacedEvent(@TargetAggregateIdentifier val id: Long, val order: OrderWriteModel)@Entity
@Table(name = "orders")
class OrderWriteModel {
@Id
@GeneratedValue
var id: Long? = null
private set
}interface OrderCommandRepo : org.springframework.data.repository.CrudRepository<OrderWriteModel, Long>
commandGateway.send<Long>(PlaceOrderCommand())
Handling:
@Aggregate
class OrderAggregate {
@AggregateIdentifier
var id: Long? = null
@AggregateMember
var order: OrderWriteModel? = null
constructor()
@CommandHandler
constructor(placeOrderCommand: PlaceOrderCommand, repo: OrderCommandRepo) {
val savedOrder = repo.save(OrderWriteModel())
AggregateLifecycle.apply(OrderPlacedEvent(savedOrder.id!!, savedOrder))
}
@EventSourcingHandler
fun orderPlaced(orderPlacedEvent: OrderPlacedEvent) {
id = orderPlacedEvent.id
order = orderPlacedEvent.order
}
}Saving an order to the write database before applying an event makes me a bit nervous, am I doing it wrong?I could ask the database for the next sequence value in controller and then I would only save the order inside event handler but I feel like it's better when Hibernate does it for me, isn't it?
@Entity
@Table(name = "orders")
data class OrderWriteModel(@Id val id: Long)
interface OrderCommandRepo : CrudRepository<OrderWriteModel, Long> {
@Query(value = "select nextval('hibernate_sequence')", nativeQuery = true)
fun getNextId(): Long
}
fun placeOrder(): Long {
val id = orderCommandRepo.getNextId()
return commandGateway.send<Long>(PlaceOrderCommand(id))
}
@Aggregate
class OrderAggregate {
@AggregateIdentifier
var id: Long? = null
@AggregateMember
lateinit var order: OrderWriteModel
@Suppress("ConvertSecondaryConstructorToPrimary")
@CommandHandler
constructor(placeOrderCommand: PlaceOrderCommand) {
AggregateLifecycle.apply(OrderPlacedEvent(placeOrderCommand.id))
}
@EventSourcingHandler
fun orderPlaced(orderPlacedEvent: OrderPlacedEvent, repo: OrderCommandRepo) {
id = orderPlacedEvent.id
order = repo.save(OrderWriteModel(orderPlacedEvent.id))
}
}
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/axonframework/07082a01-8c2d-413b-aeed-a97e59d02647%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
data class PlaceOrderCommand(@TargetAggregateIdentifier val id: Long)
data class OrderPlacedEvent(@TargetAggregateIdentifier val id: Long)
@Entity
@Table(name = "orders")
@Aggregate
class OrderAggregate {
@Id
val id: Long
@Suppress("ConvertSecondaryConstructorToPrimary")
@CommandHandler
constructor(placeOrderCommand: PlaceOrderCommand) {
id = placeOrderCommand.id
AggregateLifecycle.apply(OrderPlacedEvent(placeOrderCommand.id))
}
}interface OrderCommandRepo : org.springframework.data.repository.Repository<OrderAggregate, Long> {
@Query(value = "select nextval('hibernate_sequence')", nativeQuery = true)
fun getNextId(): Long
}
fun placeOrder(): Mono<Long> {
val id = orderCommandRepo.getNextId()
return commandGateway.send<Long>(PlaceOrderCommand(id)).toMono()
}
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/axonframework/92e4e090-9108-4633-af20-9e916a7b6150%40googlegroups.com.
@CommandHandler
annotation is placed on an aggregate's constructor, the respective command will create a new instance of that aggregate and add it to the repository. Those commands do not require to target a specific aggregate instance. Therefore, those commands do not require any @TargetAggregateIdentifier
or @TargetAggregateVersion
annotations, nor will a custom CommandTargetResolver
be invoked for these commands.It is also mentioned in the "Note" on the same page:When the@CommandHandler
annotation is placed on an aggregate's constructor, the respective command will create a new instance of that aggregate and add it to the repository. Those commands do not require to target a specific aggregate instance. Therefore, those commands do not require any@TargetAggregateIdentifier
or@TargetAggregateVersion
annotations, nor will a customCommandTargetResolver
be invoked for these commands.
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/axonframework/d6b84409-c119-4228-9907-587b8126811e%40googlegroups.com.