DataIntegrityViolationException:无法使用 spring mongodb 存储 JSON 架构

DataIntegrityViolationException: Unable to store JSON Schema with spring mongodb

我有一个 JSON 架构,如下所示,我通过 websocket 将其发送到我的后端。

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

我的 bean class 定义为

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 的有效密钥,我想把它撕成这样。 有解决办法吗?

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

您可以在处理 storage/retrieval 这些对象的层中编写此逻辑。

当我通过将数据作为字符串传输的 websocket 发送数据时,我将 $ref 替换为一些字符串(比如 ##ref##),这是 [=20= 的有效键名].

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

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

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