如何在没有 _class 属性的情况下将 spring 数据与 couchbase 一起使用

有没有一种简单的方法可以将 spring data couchbase 与没有 _class 属性的文档一起使用?在沙发上,我的 sampledata 存储桶中有类似的东西:

Is there a simple way to use spring data couchbase with documents that do not have _class attribute? In the couchbase I have something like this in my sampledata bucket:

{
  "username" : "alice", 
  "created" : 1473292800000,
  "data" : { "a": 1, "b" : "2"},
  "type" : "mydata"
}

现在,有什么方法可以定义从这种文档结构到 Java 对象的映射(注意 _class 属性丢失并且无法添加),反之亦然,以便我得到所有(或大多数) 来自 spring couchbase 数据的自动功能?

Now, is there any way to define mapping from this structure of document to Java object (note that _class attribute is missing and cannot be added) and vice versa so that I get all (or most) automagical features from spring couchbase data?

类似:如果 type 字段的值为mydata",则使用类 MyData.java.因此,当执行查找而不是自动添加 AND _class = "mydata" 到生成的查询时添加 AND type = "mydata".

Something like: If type field has value "mydata" use class MyData.java. So when find is performed instead of automatically adding AND _class = "mydata" to generated query add AND type = "mydata".

推荐答案

Spring Data 通常需要 _class 字段来知道在反序列化时要实例化回什么.

Spring Data in general needs the _class field to know what to instantiate back when deserializing.

通过覆盖 AbsctractCouchbaseDataConfiguration 中的 typeKey() 方法,在 Spring Data Couchbase 中使用与 _class 不同的字段名称相当容易.

It's fairly easy in Spring Data Couchbase to use a different field name than _class, by overriding the typeKey() method in the AbsctractCouchbaseDataConfiguration.

但默认情况下它仍然需要一个完全限定的类名

解决这个问题需要更多的工作:

Getting around that will require quite a bit more work:

  1. 您需要按照 DefaultCouchbaseTypeMapper 的模型实现自己的 CouchbaseTypeMapper.在 super(...) 构造函数中,您需要提供一个附加参数:TypeInformationMapper 列表.默认实现没有显式提供一个,因此使用了 SimpleTypeInformationMapper,它是放置 FQN 的那个.
  2. 还有一个可配置的替代实现,因此您可以通过 Map 将特定类别名为更短的名称:ConfigurableTypeInformationMapper...
  3. 因此,通过将 ConfigurableTypeInformationMapper 与特定类所需的别名 + SimpleTypeInformationMapper 放在列表中(如果您序列化了您没有'不提供别名),你可以实现你的目标.
  4. typeMapperMappingCouchbaseConverter 中使用,不幸的是,您还需要扩展它(只是为了实例化您的 typeMapper 而不是默认.
  5. 一旦你有了它,再次覆盖配置以返回使用自定义 CouchbaseTypeMapper 的自定义 MappingCouchbaseConverter 实例(mappingCouchbaseConverter() 方法).
  1. You'll need to implement your own CouchbaseTypeMapper, following the model of DefaultCouchbaseTypeMapper. In the super(...) constructor, you'll need to provide an additional argument: a list of TypeInformationMapper. The default implementation doesn't explicitly provide one, so a SimpleTypeInformationMapper is used, which is the one that puts FQNs.
  2. There's an alternative implementation that is configurable so you can alias specific classes to a shorter name via a Map: ConfigurableTypeInformationMapper...
  3. So by putting a ConfigurableTypeInformationMapper with the alias you want for specific classes + a SimpleTypeInformationMapper after it in the list (for the case were you serialize a class that you didn't provide an alias for), you can achieve your goal.
  4. The typeMapper is used within the MappingCouchbaseConverter, which you'll also need to extend unfortunately (just to instantiate your typeMapper instead of the default.
  5. Once you have that, again override the configuration to return an instance of your custom MappingCouchbaseConverter that uses your custom CouchbaseTypeMapper (the mappingCouchbaseConverter() method).

相关文章