DataIntegrityViolationException:无法使用spring mongodb存储JSON Schema

时间:2017-04-26 07:17:34

标签: java spring mongodb spring-data spring-data-mongodb

我有一个JSON模式,如下所示,我通过websocket发送到我的后端。

{
    "type": "object",
    "properties": {
        "user": {
            "$ref": "#/definitions/user"
        }
    },
    "required": [
        "user"
    ]
}

我的bean类被定义为

class Schema{
    private String type;
    private String[] required;
    Private Map<String, Object> properties;
    //getter and setter
}

现在我想将它存储在mongodb中,但是当我尝试这样做时,我会遇到异常

org.springframework.dao.DataIntegrityViolationException: Write failed with error code 55 and error message 'The DBRef $ref field must be following by a $id field'; nested exception is com.mongodb.WriteConcernException: Write failed with error code 55 and error message 'The DBRef $ref field must be following by a $id field'
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:85) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2135) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:481) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.saveDBObject(MongoTemplate.java:1101) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1034) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:981) ~[spring-data-mongodb-1.10.1.RELEASE.jar:na]

我猜测$ ref不是在mongodb中使用的有效密钥名称,但它是基于Open API规范的JSON Schema的有效密钥,我想按原样撕掉它。 对此有什么解决方案吗?

2 个答案:

答案 0 :(得分:1)

根据this mongodb JIRA,您无法保存包含.或以$开头的密钥。因此,我认为此处唯一的解决方案是在将对象存储到$之前手动转义mondogb并在检索对象时删除\\

您可以在处理这些对象的存储/检索的层中编写此逻辑。

答案 1 :(得分:0)

当我通过websocket发送数据时,我将其作为字符串传输,我将$ref替换为一些字符串(例如##ref##),这是mongodb的有效密钥名称。

strData = strData.replace(new RegExp('"\\$ref":', 'g'), '"##ref##":');
self.stomp.send('/app/execute', {}, strData);

当我从后端收到它时,我再次将##ref##替换为$ref

body = body.replace(new RegExp('"##ref##":', 'g'), '"$ref":');