找不到java.lang.Object的映射元数据 - Couchbase

时间:2016-03-15 04:58:03

标签: couchbase spring-data-couchbase

我在CouchBase存储库中持久化实体并尝试查询它。该实体看起来像这样:

@Document(expiry = 0)
public class GsJsonStore implements Serializable {
    private static final long serialVersionUID = 7133072282172062535L;
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;
    @Field
    private Map<String,Object> _object;
    @Field
    private String _subject;
    @Field
    private String _predicate;
    //Getters and Setters 
    }

我在CouchbaseOperations模板上使用N1QL查询来查询实体,如下所示:

String query1 =  "SELECT META(default).id as _ID, META(default).cas as _CAS, default.* FROM default WHERE "+key+"="+"'"+value+"'";

List<GsJsonStore> list = operations.findByN1QL(N1qlQuery.simple(query1), GsJsonStore.class);

我在_object Map中查询K-V对。我收到错误:No mapping metadata found for java.lang.Object

为什么会这样?另外,我在Couchbase中将json对象存储为Map<String,Object>,我尝试使用jackson JsonNode类型,但该对象还存储了与类相关的元数据。是否有更好的数据类型来表示json类型?

修改

存储在Couchbase中的数据:

{
"_object" : {
"Name" : "Kapil",
"Age" : {
"Nested" : 21
}
},
"_subject" : "Subject",
"_predicate" : "Predicate"
}

我正在寻找的关键是_object.Name,值是'Kapil'

2 个答案:

答案 0 :(得分:5)

正如here所述,您应该覆盖默认的SPMappingCouchbaseConverter。

以下是我解决问题的方法:

order date

答案 1 :(得分:0)

如果您绝对需要Map

看起来问题有两个:

  1. 使用带参数的构造函数通过反射进行重新实例化似乎从我的测试中得到了很好的效果,因此我添加了一个私有的空构造函数private GsJsonStore() {}
  2. 您存储的Map包含另一级别的嵌套,也是一般的Map。这对于在反序列化时处理的框架来说是个问题。
  3. 你可以尝试扁平化#34;年龄&#34;进入顶级_object地图或为&#34;年龄&#34;创建专用课程条目(简单地使用类型为int的Nested字段)并存储它。请注意,在后一种情况下,框架应将_class元数据添加到&#34; Age&#34;存储的JSON,解释了在这种情况下它如何设法在以后反序列化它。

    如果您可以比Map 更具体地进行模型化:

    最好的方法仍然是创建一个没有泛型集合/映射但是命名属性的正确GsEntity类(也可能是子值的有意义的实体类)。

    这将缓解Map的问题,并允许通过在存储库界面中添加方法签名来自动创建查询。这样的事情:

    public class ContentObject {
    
        private String name;
        private int age;
    
        public ContentObject(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    @Document(expiry = 0)
    public class GsEntity implements Serializable {
    
        private static final long serialVersionUID = 7133072282172062535L;
    
        @Id
        private String id;
    
        @Field
        private ContentObject object;
    
        @Field
        private String subject;
    
        @Field
        private String predicate;
    
        //EMPTY CONSTRUCTOR
    
        //Getters and Setters 
    }
    
    public interface GsEntityRepository extends CouchbaseRepository<GsEntity, String> {
    
        @Query
        List<GsEntity> findByObjectNameEquals(String nameValue);
    }
    

    请注意,已重命名属性以删除下划线,因为它不遵循Java命名约定,并且会阻止界面方法正确映射到属性。

    该方法的分析大致如下:findBy Object Name Equals。 这转换为SELECT GsEntity个对象,object字段有一个name字段,其值与作为参数传递的字符串相同。