我在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
为什么会这样?另外,我将一个json对象存储为Couchbase中的 Map<String,Object>
,我尝试使用jackson JsonNode
类型,但该对象也存储了类相关的元数据 . 是否有更好的数据类型来表示json类型?
EDIT
存储在Couchbase中的数据:
{
"_object" : {
"Name" : "Kapil",
"Age" : {
"Nested" : 21
}
},
"_subject" : "Subject",
"_predicate" : "Predicate"
}
我正在寻找的关键是_object.Name,值是'Kapil'
2 回答
正如here所解释的那样,您应该覆盖默认的SPMappingCouchbaseConverter .
这是我解决问题的方法:
If you absolutely need the Map :
看起来问题是双重的:
通过反射使用带参数的构造函数重新实例化't seem to work that well from my tests, so I' d添加一个私有的空构造函数
private GsJsonStore() {}
.您存储的
Map
包含另一级别的嵌套,也是一般的Map
. 这对于在反序列化时处理的框架是有问题的 .您可以尝试将"Age"展平到顶级
_object
Map 中,或者为"Age"条目创建一个专用类(只需使用int类型的Nested
字段)并存储它 . 请注意,在后一种情况下,框架应该将_class
元数据添加到存储的"Age" JSON中,这解释了在这种情况下它如何设法在以后对其进行反序列化 .If you can modelize more specifically than a Map :
最好的方法仍然是创建一个没有泛型集合/映射但是命名属性的正确
GsEntity
类(也可能是子值的有意义的实体类) .这将缓解
Map
的问题,并允许通过在存储库接口中添加方法签名来自动创建查询 . 像这样的东西:请注意,已重命名属性以删除下划线,因为它不遵循Java命名约定,并且会阻止接口的方法正确映射到属性 .
该方法大致分析如下:
findBy
Object
Name
Equals
. 这转换为GsEntity
对象的SELECT,其中object
字段具有name
字段,该字段与作为参数传递的字符串具有相同的值 .