在Spring转换器中,有没有一种方法可以将NULL转换为某个值?

8

数据库(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问题有关带有默认值的修改表格


呈现得很好。你能添加一下你正在发送请求的代码吗? - Vinetos
你能提供一个MRE吗? - 123
我对使用的存储库/实体添加了更多上下文 - 这样够了吗? @123你是指GitHub存储库之类的形式吗?这可能需要一些时间才能梳理清楚。我认为“真正”的解决方案是关于Spring或Cassandra的某些我所缺少的东西。 - nikeee
@nikeee 一个 Github 仓库可能是最有帮助的,但它与 StackExchange 的格式有些冲突。我指的基本上就是你现在编辑的部分,谢谢。 - 123
实际上,这是首选方法。 Converter.convert(...)接受非空输入类型。在从Cassandra检索值期间,列值为“null”,因此无法检索转换器的源类型。 - mp911de
显示剩余5条评论
1个回答

1

Cassandra具有稀疏存储,这意味着如果未设置列(在RDBMS中的字段),则不会存储它们。因此,说“新列是null”是不正确的。

如果您正在使用预准备语句,则需要使用本机协议v3调用BoundStatement.unset(),以便不会针对null值生成墓碑标记。

否则,在本机协议v4(Cassandra 2.2或更高版本)中,将变量保留未设置即可。干杯!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接