axon聚合标识符类型转换器

jutyujz0  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(285)

问题:处于聚合状态的axon springboot应用程序 @AggregateIdentifier 属于类型 UUID postgresql数据库列的类型为 UUID . 当在create命令上持久化时-标识符被成功存储。在发送更新命令时,警告会上升,并且命令不会传递到聚合处理程序,因为 @TargetAggregateIdentifier 这里需要axon描述的字符串类型:
java.lang.illegalargumentexception:为类…myaggregate提供了错误类型的id。应为:class java.util.uuid,get class java.lang.string
研究:
有效的解决方案是将域重构为 String 所有聚合标识符的类型。数据库 @Id 归档也应转换为 varchar(36) 要存储的类型 UUID.toString() 作为主键。主要的缺点是它效率低下:9倍大的大小和较慢的字符串读取。
最小的样板和折衷方案是将域重构为 String 所有骨料指示剂的类型和用途 javax.persistence.Converters 要在持久化时将jpa层中的字符串转换为uuid,请执行以下操作:

  1. @Converter
  2. public class UuidJpaConverter implements AttributeConverter<String, UUID> {
  3. @Override
  4. public UUID convertToDatabaseColumn(String uuid) {
  5. return fromString(uuid);
  6. }
  7. @Override
  8. public String convertToEntityAttribute(UUID uuid) {
  9. return uuid.toString();
  10. }
  11. }
  12. ...
  13. @Aggregate
  14. @Entity
  15. @IdClass(UuidKey.class)
  16. public class MyAggregate implements Serializable {
  17. @AggregateIdentifier
  18. @Id
  19. private String uuid;
  20. ...
  21. }
  22. public class UuidKey implements Serializable {
  23. @Column(name = "uuid", nullable = false, updatable = false)
  24. @Convert(converter = UuidJpaConverter.class)
  25. private String uuid;
  26. }

但结果是:
o、 h.engine.jdbc.spi.sqlexceptionhelper:错误:列“uuid”的类型为uuid,但表达式的类型为bytea
使用axon identifier converter,但它要求为每个聚合使用自定义genericjparepository,并且实际上从不在断点上调用identifierconverter处理程序:

  1. @Configuration
  2. public class IdentifierConverter {
  3. @Bean
  4. public GenericJpaRepository<MyAggregate> aggregateJpaRepository(
  5. EntityManagerProvider provider,
  6. @Qualifier("eventBus") EventBus simpleEventBus) {
  7. GenericJpaRepository<MyAggregate> repository = GenericJpaRepository
  8. .builder(MyAggregate.class)
  9. -> .identifierConverter(name -> UUID.fromString(name))
  10. .entityManagerProvider(provider)
  11. .eventBus(simpleEventBus)
  12. .build();
  13. return repository;
  14. }
  15. }

结果是:
o、 h.engine.jdbc.spi.sqlexceptionhelper:错误:列“uuid”的类型为uuid,但表达式的类型为character variable
还有一个建议的通用genericjparepository解决方案,可以找到聚合标识符的类型,除非它已经是一个字符串,否则可以通过spring转换服务转换它。但目前还不清楚该将其绑定到何处 registerAggregateBeanDefinitions 在configurer中,当我们有axon自动配置并且bean被期望支持configurer时:

  1. final Class<?> aggregateIdentifierType = Stream.of( aggregateType.getDeclaredFields( ) )
  2. .filter( field -> field.isAnnotationPresent( AggregateIdentifier.class ) )
  3. .map( field -> field.getType( ) )
  4. .findFirst( )
  5. .orElseThrow( ( ) -> new IllegalStateException( "The aggregate '" + aggregate + "' does not have an identifier." ) );
  6. aggregateConf.configureRepository(
  7. c -> GenericJpaRepository.builder( aggregateType )
  8. .identifierConverter( string -> {
  9. if ( aggregateType == String.class ) {
  10. return string;
  11. } else {
  12. try {
  13. final ConversionService conversionService = beanFactory.getBean( ConversionService.class );
  14. return conversionService.convert( string, aggregateIdentifierType );
  15. } catch ( final NoSuchBeanDefinitionException ex ) {
  16. throw new IllegalStateException( "Unable to convert String to aggregate identifier of type '" + aggregateIdentifierType.getName( ) + "'. A conversion service is missing." );
  17. }
  18. }
  19. } )
  20. ...
  21. @Named
  22. final class MyIdConverter implements Converter<String, MyId> {
  23. ...
  24. @Override
  25. public MyId convert( final String source ) {
  26. return MyId.fromString( source );
  27. }
  28. }

问题:如何在postgresql数据库中保留聚合标识符的uuid类型 UUID 作为首选类型 @AggregateIdentifier 或者至少 String . 也为什么只是 String 如果在2010年uuid在axon中被广泛使用,那么目前是否支持?

4ioopgfo

4ioopgfo1#

老实说,你在这里对这件事做得很深入。我不确定是否能充分帮助你,但无论如何我都会试一试。
研究点1显然是让事情立即运转的最务实的解决方案。如果你要注意到 String 相比 UUID 是我很难接受的。所以如果这是绝对的不,调查应该继续。否则,它当然会完成任务。
说到第2点和第3点的研究,我相信您遇到了postgresql使用方言的问题,尽管我不是100%确定。尤其是postgresql提供了一些“很棒”的类型,但这些类型并不总是在所有场景中自动工作。我的“猜测”是基于强迫postgresql使用 BYTEA 而不是 OID 如果你想的话,你应该降低博士后的吐司能力。如果您选择在事件存储中使用postgres,并且希望能够实际看到事件的内容,那么这将变得特别方便。这个博客文章举例说明了如何处理这个问题。更重要的是,这篇博文展示了如何调整所使用的方言。也许这能为你提供解决方案2和3?
在这种情况下,选择4应该是最合理的解决方案。但我从你的React中得知,你目前还没有成功。当轴突和Spring结合时 SpringAxonAutoConfigurer (您指的是 registerAggregateBeanDefinitions 方法)将自动检查聚合上的可配置bean。它是基于 @Aggregate (即axon的spring原型注解)。更具体地说,您可以使用 repository 中的字段 @Aggregate 定义要使用的存储库的bean名称。
因此,您应该能够简单地提供 GenericJpaRepository 用想要的豆子 identifierConverter . 该bean的名称不能在 @Aggregate 在您的 MyAggregate ,以便axon的自动配置可以正确地获取它。希望这对你有帮助!

相关问题