数据库(Cassandra)在添加新列时不允许指定默认值。因此,对于每一行,新的列都是null
。
现在,我们为实体添加了一个标志(将来可能会有更多的条目):
enum UsageFlag {
OTHER,
SPECIAL_VALUE,
}
我们还添加了一个ReadingConverter:
@ReadingConverter
public class UsageFlagReadingConverter implements Converter<String, UsageFlag> {
@Nonnull
@Override
public UsageFlag convert(String source) {
return source == null
? UsageFlag.OTHER
: UsageFlag.valueOf(source);
}
}
在解析任何非空值作为枚举成员时,它基本上应将null
视为UsageFlag.OTHER
。
然而,这并不起作用,因为根据Spring文档,只有在值不是null
时才会调用{{link1:Converter的convert方法}}。由于这个原因,如果数据库中的字段为null
,那么该实体的字段仍然为null
。只有当存在值时,它才能正常工作。由于创建整个列时都为空,这完全违背了ReadingConverter
的目的。
Cassandra似乎不支持为每行设置值(例如UPDATE foo SET flag='OTHER' WHERE True
),因此这似乎是一个很好的选择。我们想避免手动触摸数据库中的每一行。
有没有办法可以使用Spring来帮助解决这个问题?或者是否有一种使用CQL或Cassandra解决这个问题的方法?
编辑:关于设置的更多上下文:
public interface FancyEntityRepository extends MapIdCassandraRepository<FancyEntity> {
}
public class FancyEntity {
@PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private string id;
private UsageFlag usage;
// other columns omitted
// getters and setter omitted for this example
}
// Somewhere in a service:
FancyEntity fe = fancyEntityRepository.findOne("1");
System.out.println(fe.getUsage());
但我认为转换器的行为并不是特定于Cassandra的。
表格是这样创建和修改的:
CREATE TABLE FancyEntity (
id TEXT,
-- other columns omitted
PRIMARY KEY (id)
);
ALTER TABLE FancyEntity ADD (
usage TEXT
);
ALTER TABLE的Cassandra文档以及一个相关的SO问题有关带有默认值的修改表格。
Converter.convert(...)
接受非空输入类型。在从Cassandra检索值期间,列值为“null”,因此无法检索转换器的源类型。 - mp911de