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":');
我有一个 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":');