将null读取为springdata cassandra中的空集



我使用弹簧数据cassandra,并有这样的实体:

@Table("users")
public class User {
@Column("permissions")
@CassandraType(type = DataType.Name.SET, typeArguments = {DataType.Name.TEXT})
public Set<String> permissions = new HashSet<>(); 
}

在cassandra中,我有一个表users,其中字段permissions类型为Set。当我在集合中存储一些值时,它工作得很好,但当我尝试存储空集时,当我从存储库中读取这样的实体时,它变成了null

有没有办法强制弹簧数据cassandra将null更改为空HashSet?或者我可以以某种方式为实体的这个特定属性添加自定义读取器吗?

TL;DR

这是Cassandra为空的Collection和Map类型列返回null的默认行为。

进一步阅读

Cassandra为不包含任何项的列表、集合和映射返回null值。当使用具有预初始化字段的类时,这尤其令人遗憾,如您的问题中所示。问题跟踪器中有一个打开的票证(DATACASS-266-加载空集合类型的属性会覆盖预先初始化的字段(-截至目前,没有评论或投票。

我们不确定在处理空(null(集合时跳过设置属性还是应用某种默认值是个好主意,因为这引发了后续问题:

  • 通过构造函数创建实例:在这种情况下需要一个值。对于属性访问,我们可以省略设置属性,对于构造函数创建,我们必须提供一个值
  • 预初始化的集合包含项目,但从Cassandra收到的集合是null
  • 我们假设,更改将被应用,假设空集合默认为null的现有代码会发生什么

解决此行为的一种可能性可以是MappingCassandraConverter上的配置或要覆盖的扩展点,以便用户可以应用自己的空集合行为。

我也一直在尝试消除模型对象中的null集合,虽然目前在Spring Data级别(版本2.1.x(可能无法做到这一点,但您可以考虑一些选项:

  • 对有问题的字段使用属性访问(即使用注释@AccessType(PROPERTY)(,在setter方法中,当参数为null时,将字段设置为空集合
  • 定义一个兼容的构造函数(见下文(,当提供null时,该构造函数将字段设置为空集合(如果模型是可变的,您可能仍然希望如上所述提供setter(

有一些注意事项可以确保Spring Data Cassandra使用所需的构造函数(例如,不要提供无参数构造函数(,因此查看参考指南的"对象映射基础"部分至关重要(https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#mapping.fundamentals)。

该参考指南中的建议之一(至少从2.1版开始(是使用全参数构造函数并使模型对象不可变,这将与处理null的基于构造函数的方法很好地配合使用。尽管这意味着编写和维护构造函数来处理null,而不是依赖Lombok的@AllArgsConstructor

我在一个案例中使用了属性访问方法,但没有使用构造函数方法。然而,当添加新的或模型类时,我确实打算走构造函数的路线(我是不可变对象的粉丝,即使没有任何集合字段,我也会探索这条路线(

我相信Spring Data Cassandra 2.0还添加了持久性生命周期回调,这是我认为的另一个可能的选择,但我排除了这一可能性,主要是因为逻辑不会驻留在模型类本身中(也违背了框架创建者的建议(

最新更新