【问题标题】:_class property in CouchBaseCouchBase 中的 _class 属性
【发布时间】:2018-11-15 05:49:51
【问题描述】:

我有一个存储在 Couchbase 中的文档。

{
  "a": {
    "b": {
      "key":"Value"
    },
 "_class":"com.nikhil.model"
  },
    "c":{
      "d":{
        "key":"value"
       },
  // _class is missing here
     },
      "_class": "com.nikhil.model"
 }

如您所见,我在文档的“d”中没有 _class,因此我无法获取此文档。对象映射异常来了。 _class 用于将 couchbase 的嵌套对象映射到映射所需的模型,但在“c”对象内部我没有这个 _Class 属性,这就是映射异常出现的原因。 有什么解决办法吗?

【问题讨论】:

  • 此 json 无效(即使删除评论),您可能需要更新它以确保准确性(如果需要帮助,请查看 jsonlint.com)

标签: couchbase spring-data-couchbase


【解决方案1】:

如果您使用 Spring boot,则需要覆盖扩展 AbstractCouchbaseConfiguration 的 Couchbase 配置文件中的 typekey() 方法并返回 MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE。这将在 Couchbase Server 中存储的文档中将您的 _class 替换为 javaClass 字符串。我希望这会有所帮助。

@Configuration
public class RemoteCouchbaseConfiguration extends AbstractCouchbaseConfiguration {

    @Value("${couchbase.host}")
    private String host;

    @Value("${couchbase.bucket.bucketName}")
    private String bucketName;

    @Value("${couchbase.bucket.password}")
    private String password;

    @Override
    protected List<String> getBootstrapHosts() {
        return Arrays.asList(this.host);
    }

    @Override
    protected String getBucketName() {
        return this.bucketName;
    }

    @Override
    protected String getBucketPassword() {
        return this.password;
    }

    @Override
    public String typeKey() {
        return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE;
    }
}

【讨论】:

    【解决方案2】:

    看起来你正在使用带有 Spring Data 的 Couchbase,最简单的方法是返回一个投影:

    @Override
    public List<UserVO> getUsers(String companyId, List<String> userIds) {
    
        String queryString =  "SELECT meta(t).id as id, t.login as login, t.firstName as firstName from " + getBucketName() + " t where t."+getClassFilter()+" "
                + " and t.companyId = '" + companyId + "' and t.isEnabled = true and t.isVisible = true "
                + " and meta(t).id in ["+userIds.stream().map(e->"'"+e+"'").collect( Collectors.joining( "," )) +"]";
        N1qlParams params = N1qlParams.build().consistency(ScanConsistency.NOT_BOUNDED).adhoc(true);
        ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);
    
        return   userRepository.getCouchbaseOperations().findByN1QLProjection(query, UserVO.class);
    }
    

    【讨论】:

    • 我们不能像使用 JPA 一样使用 Spring 存储库吗?
    【解决方案3】:

    您可以使用如下所示的 UPDATE N1QL 语句向其添加 _class:

    UPDATE mybucket b
    SET b.c.d._class = 'com.foo.bar'
    WHERE b.c.d IS NOT MISSING
    AND b.c.d._class IS MISSING
    

    这将更新在“c”对象中具有“d”对象但在 c 对象中没有“_class”的任何文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      相关资源
      最近更新 更多