问题描述
有没有一种简单的方法可以将 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:
- 您需要按照 DefaultCouchbaseTypeMapper 的模型实现自己的 CouchbaseTypeMapper.在 super(...) 构造函数中,您需要提供一个附加参数:TypeInformationMapper 列表.默认实现没有显式提供一个,因此使用了 SimpleTypeInformationMapper,它是放置 FQN 的那个.
- 还有一个可配置的替代实现,因此您可以通过 Map 将特定类别名为更短的名称:ConfigurableTypeInformationMapper...
- 因此,通过将 ConfigurableTypeInformationMapper 与特定类所需的别名 + SimpleTypeInformationMapper 放在列表中(如果您序列化了您没有'不提供别名),你可以实现你的目标.
- typeMapper 在 MappingCouchbaseConverter 中使用,不幸的是,您还需要扩展它(只是为了实例化您的 typeMapper 而不是默认.
- 一旦你有了它,再次覆盖配置以返回使用自定义 CouchbaseTypeMapper 的自定义 MappingCouchbaseConverter 实例(mappingCouchbaseConverter() 方法).
- 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.
- There's an alternative implementation that is configurable so you can alias specific classes to a shorter name via a Map: ConfigurableTypeInformationMapper...
- 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.
- The typeMapper is used within the MappingCouchbaseConverter, which you'll also need to extend unfortunately (just to instantiate your typeMapper instead of the default.
- Once you have that, again override the configuration to return an instance of your custom MappingCouchbaseConverter that uses your custom CouchbaseTypeMapper (the mappingCouchbaseConverter() method).