英文:
How to create custom conversions for Spring Data Cassandra?
问题
I'm not able to create custom conversions in order to use Currency and Locale as data types.
I'm using a @Configuration
annotated class which will be auto-configured with META-INF/spring.factories
:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.acme.autoconfigure.ConverterAutoConfiguration
I tried registering the converters directly as beans and also tried to create CassandraCustomConversions
bean without success:
@Configuration
public class ConverterAutoConfiguration {
/*
@Bean
public Converter<String, Currency> currencyReadConverter() {
// ...
}
@Bean
public Converter<Currency, String> currencyWriteConverter() {
// ...
}
@Bean
public Converter<String, Locale> localeReadConverter() {
// ...
}
@Bean
public Converter<Locale, String> localeWriteConverter() {
// ...
}
*/
@Bean
public CassandraCustomConversions cassandraCustomConversions() {
// ...
}
enum CurrencyReadConverter implements Converter<String, Currency> {
// ...
}
enum CurrencyWriteConverter implements Converter<Currency, String> {
// ...
}
enum LocaleReadConverter implements Converter<String, Locale> {
// ...
}
enum LocaleWriteConverter implements Converter<Locale, String> {
// ...
}
}
With the CassandraCustomConversions
bean I'm getting an exception directly at startup:
Caused by: org.springframework.data.mapping.MappingException: Cannot resolve DataType for type [class java.lang.String] for property [categoryId] in entity [com.acme.model.Category]; Consider registering a Converter or annotating the property with @CassandraType.
It seems it's losing all the default mappings.
When using the converter beans directly I'm getting the following exception:
org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract reactor.core.publisher.Flux com.acme.repository.CategoryLocaleReactiveRepository.findByUriNameInAndKeyLocale(java.util.Collection,java.util.Locale)! Reason: Could not inline literal of type java.util.Locale. This happens because the driver doesn't know how to map it to a CQL type. Try passing a TypeCodec or CodecRegistry to literal().
Based on this issue this should be possible somehow: link to GitHub issue
英文:
I'm not able to create custom conversions in order to use Currency and Locale as data types.
I'm using a @Configuration
annotated class which will be auto-configured with META-INF/spring.factories
:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.acme.autoconfigure.ConverterAutoConfiguration
I tried registering the converters directly as beans and also tried to create CassandraCustomConversions
bean without success:
@Configuration
public class ConverterAutoConfiguration {
/*
@Bean
public Converter<String, Currency> currencyReadConverter() {
return new Converter<String, Currency>() {
@Override
public Currency convert(String source) {
return Currency.getInstance(source);
}
};
}
@Bean
public Converter<Currency, String> currencyWriteConverter() {
return new Converter<Currency, String>() {
@Override
public String convert(Currency source) {
return source.toString();
}
};
}
@Bean
public Converter<String, Locale> localeReadConverter() {
return new Converter<String, Locale>() {
@Override
public Locale convert(String source) {
return StringUtils.parseLocaleString(source);
}
};
}
@Bean
public Converter<Locale, String> localeWriteConverter() {
return new Converter<Locale, String>() {
@Override
public String convert(Locale source) {
return source.toString();
}
};
}
*/
@Bean
public CassandraCustomConversions cassandraCustomConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(CurrencyReadConverter.INSTANCE);
converters.add(CurrencyWriteConverter.INSTANCE);
converters.add(LocaleReadConverter.INSTANCE);
converters.add(LocaleWriteConverter.INSTANCE);
return new CassandraCustomConversions(converters);
}
enum CurrencyReadConverter implements Converter<String, Currency> {
INSTANCE;
@Override
public Currency convert(String source) {
return Currency.getInstance(source);
}
}
enum CurrencyWriteConverter implements Converter<Currency, String> {
INSTANCE;
@Override
public String convert(Currency source) {
return source.toString();
}
}
enum LocaleReadConverter implements Converter<String, Locale> {
INSTANCE;
@Override
public Locale convert(String source) {
return StringUtils.parseLocaleString(source);
}
}
enum LocaleWriteConverter implements Converter<Locale, String> {
INSTANCE;
@Override
public String convert(Locale source) {
return source.toString();
}
}
}
With the CassandraCustomConversions
bean I'm getting an exception directly at startup:
Caused by: org.springframework.data.mapping.MappingException: Cannot resolve DataType for type [class java.lang.String] for property [categoryId] in entity [com.acme.model.Category]; Consider registering a Converter or annotating the property with @CassandraType.
It seems its loosing all the default mappings.
When using the converter beans directly I'm getting the following exception:
org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract reactor.core.publisher.Flux com.acme.repository.CategoryLocaleReactiveRepository.findByUriNameInAndKeyLocale(java.util.Collection,java.util.Locale)! Reason: Could not inline literal of type java.util.Locale. This happens because the driver doesn't know how to map it to a CQL type. Try passing a TypeCodec or CodecRegistry to literal().
Based on this issue this should be possible somehow: https://github.com/spring-projects/spring-boot/issues/8411
答案1
得分: 3
尝试将@WritingConverter
和@ReadingConverter
添加到您的转换器中。我相信Spring在决定使用哪个转换器与非自定义类型一起使用时会有些困难。
一旦将这两个注释添加到适当的转换器中,我创建了一个本地项目,并成功实现了Locale
和Currency
的转换。
如果您仍然遇到问题,我可以将我的测试项目推送到Github并分享给您。
参考链接:https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#customconversions.java
示例项目:https://github.com/michaelmcfadyen/spring-data-cassandra-custom-converter-example
英文:
Try adding @WritingConverter
and @ReadingConverter
to your converters. I believe spring struggles a bit in deciding which converter to use with non custom types.
I created a local project and managed to get the conversion of Locale
and Currency
working once those 2 annotations were added to the appropriate converter.
I can push my test project to Github and share if you are still having issues.
Reference: https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#customconversions.java
Example Project: https://github.com/michaelmcfadyen/spring-data-cassandra-custom-converter-example
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论