Spring-Data-Cassandra:在@Query语句中将枚举数组值作为参数传递失败

问题描述

在一个利用spring-data-cassandra的spring boot 2.3.1应用程序中,我在主键中具有一个枚举属性 leadType

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("leads_by_date_and_type")
public class LeadByDateTypeOrigin {

    @PrimaryKey
    private LeadDateTypeOriginKey primaryKey;

    @Column("lead_identifier")
    @Indexed("leads_identifier")
    private Long leadIdentifier;

}


@Data
@AllArgsConstructor
@NoArgsConstructor
@PrimaryKeyClass
public class LeadDateTypeOriginKey implements Serializable {

    @PrimaryKeyColumn(name = "created_date",type = PrimaryKeyType.PARTITIONED)
    private LocalDate createdDate;

    @PrimaryKeyColumn(name = "type",type = PrimaryKeyType.PARTITIONED)
    @Indexed("leads_type")
    @CassandraType(type = CassandraType.Name.TEXT)
    private LeadType leadType;

    @PrimaryKeyColumn(name = "origin",ordinal = 0,ordering = Ordering.ASCENDING)
    @Indexed("leads_origin")
    private String origin;

    public LeadDateTypeOriginKey(XMLGregorianCalendar xmlGregorianCalendar,LeadType leadType,String origin) {
        this.createdDate = LocalDate.of(xmlGregorianCalendar.getYear(),xmlGregorianCalendar.getMonth(),xmlGregorianCalendar.getDay());
        this.leadType = leadType;
        this.origin = origin;
    }
}

我添加了一个附带的转换器

@ReadingConverter
public enum LeadTypeConverter implements Converter<LeadType,String> {
    INSTANCE;
    @Override
    public String convert(LeadType leadType) {
        return leadType.name();
    }
}

并将自定义转换器注册到配置类中,如下所示

@Configuration
@Slf4j
public class CassandraConfiguration extends AbstractReactiveCassandraConfiguration {

@Value("${spring.data.cassandra.keyspace-name}")
private String keySpaceName;

@Value("${spring.data.cassandra.local-datacenter}")
private String localDataCentre;

@Override
protected String getKeyspaceName() {
    return keySpaceName;
}

@Override
protected String getLocalDataCenter() {
    return localDataCentre;
}

@Override
public CassandraCustomConversions customConversions() {
    return new CassandraCustomConversions(
            Arrays.asList(LeadTypeConverter.INSTANCE)
    );
}

}

当我尝试执行查询方法 findBy(lead)时,

@Repository
public interface LeadRepository extends ReactiveCassandraRepository<LeadByDateTypeOrigin,LeadDateTypeOriginKey> {

    default Mono<LeadByDateTypeOrigin> findBy(@NonNull final LocalDate createdDate,@NonNull final LeadType leadType,@NonNull final String origin) {
        return findById(new LeadDateTypeOriginKey(createdDate,leadType,origin));
    }

        @Query("SELECT * FROM leads_by_date_and_type WHERE created_date <= toDate(now()) AND type IN (?0) ALLOW FILTERING")
    Flux<LeadByDateTypeOrigin> findBy(@NonNull final LeadType... leadType);

}

我收到以下错误

com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException:找不到请求的操作的编解码器:[null [Lcom.example.application.domain.LeadType;]

at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:639)
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:558)
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:95)
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:92)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2276)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.get(LocalCache.java:2044)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.get(LocalCache.java:3951)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.getOrLoad(LocalCache.java:3973)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4957)
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4963)
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry.getCachedCodec(DefaultCodecRegistry.java:117)
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.codecFor(CachingCodecRegistry.java:287)
at com.datastax.oss.driver.internal.core.cql.Conversions.encode(Conversions.java:304)
at com.datastax.oss.driver.internal.core.cql.Conversions.encode(Conversions.java:263)
at com.datastax.oss.driver.internal.core.cql.Conversions.toMessage(Conversions.java:168)
at com.datastax.oss.driver.internal.core.cql.CqlRequestHandler.<init>(CqlRequestHandler.java:173)
at com.datastax.oss.driver.internal.core.cql.CqlRequestAsyncProcessor.process(CqlRequestAsyncProcessor.java:44)
at com.datastax.oss.driver.internal.core.cql.CqlRequestAsyncProcessor.process(CqlRequestAsyncProcessor.java:29)
at com.datastax.oss.driver.internal.core.session.DefaultSession.execute(DefaultSession.java:230)
at com.datastax.oss.driver.api.core.cql.AsyncCqlSession.executeAsync(AsyncCqlSession.java:41)
at org.springframework.data.cassandra.core.cql.session.DefaultBridgedReactiveSession.lambda$execute$0(DefaultBridgedReactiveSession.java:150)
at reactor.core.publisher.Mono.lambda$fromCompletionStage$0(Mono.java:430)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
at reactor.core.publisher.Flux.subscribe(Flux.java:8325)
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:199)
at reactor.core.publisher.MonoFlatMapMany.subscribeOrReturn(MonoFlatMapMany.java:49)
at reactor.core.publisher.Flux.subscribe(Flux.java:8311)
at reactor.core.publisher.Flux.blockFirst(Flux.java:2474)

显然,问题https://jira.spring.io/browse/DATACASS-521早已解决,但似乎仅适用于非数组参数。它是spring-data-cassandra错误还是局限性?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)