axon聚合标识符类型转换器

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

问题:处于聚合状态的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,请执行以下操作:

@Converter
public class UuidJpaConverter implements AttributeConverter<String, UUID> {

  @Override
  public UUID convertToDatabaseColumn(String uuid) {
    return fromString(uuid);
  }

  @Override
  public String convertToEntityAttribute(UUID uuid) {
    return uuid.toString();
  }
}

...

@Aggregate
@Entity
@IdClass(UuidKey.class)
public class MyAggregate implements Serializable {

  @AggregateIdentifier
  @Id
  private String uuid;
  ...
}

public class UuidKey implements Serializable {

  @Column(name = "uuid", nullable = false, updatable = false)
  @Convert(converter = UuidJpaConverter.class)
  private String uuid;
}

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

@Configuration
 public class IdentifierConverter {

   @Bean
   public GenericJpaRepository<MyAggregate> aggregateJpaRepository(
       EntityManagerProvider provider,
       @Qualifier("eventBus") EventBus simpleEventBus) {

     GenericJpaRepository<MyAggregate> repository = GenericJpaRepository
         .builder(MyAggregate.class)
  ->       .identifierConverter(name -> UUID.fromString(name))
         .entityManagerProvider(provider)
         .eventBus(simpleEventBus)
         .build();

     return repository;
   }
 }

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

final Class<?> aggregateIdentifierType = Stream.of( aggregateType.getDeclaredFields( ) )
 .filter( field -> field.isAnnotationPresent( AggregateIdentifier.class ) )
 .map( field -> field.getType( ) )
 .findFirst( )
 .orElseThrow( ( ) -> new IllegalStateException( "The aggregate '" + aggregate + "' does not have an identifier." ) );

 aggregateConf.configureRepository(
 c -> GenericJpaRepository.builder( aggregateType )
         .identifierConverter( string -> {
             if ( aggregateType == String.class ) {
                 return string;
             } else {
                 try {
                     final ConversionService conversionService = beanFactory.getBean( ConversionService.class );
                     return conversionService.convert( string, aggregateIdentifierType );
                 } catch ( final NoSuchBeanDefinitionException ex ) {
                     throw new IllegalStateException( "Unable to convert String to aggregate identifier of type '" + aggregateIdentifierType.getName( ) + "'. A conversion service is missing." );
                 }
             }
         } )

 ...

 @Named
 final class MyIdConverter implements Converter<String, MyId> {

     ...

     @Override
     public MyId convert( final String source ) {
         return MyId.fromString( source );
     }

 }

问题:如何在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的自动配置可以正确地获取它。希望这对你有帮助!

相关问题