我有mongo驱动程序3.2.2,spring data mongodb 1.9.1.RELEASE。
收藏:
{
"_id": "5728a1a5abdb9c352cda6432",
"isDeleted": null,
"name": undefined
},
{
"_id": "5728a1a5abdb9c352cda6433",
"isDeleted": null,
"name": null
}
当我尝试用{"name":undefined}
获取记录时,我得到以下异常。
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type org.bson.BsonUndefined to type java.lang.String
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:313) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:821) ~[spring-data-mongodb-1.7.1.RELEASE.jar:?]
怎么解决这个?我有多种类型需要从BsonUndefined转换,如String,Date,PhoneNumber等...
我在我的代码上遇到了同样的问题。我不知道为什么但是由于某种原因新的mongo-java-drivers不喜欢在数据中有一个“null”值。如果您注意到当您保存对象并且值为null时,它实际上甚至不会将该字段放在文档中以开始。
我们最终得到了一个由不同的“nodejs”应用程序编写但由java读取的集合。当我们将mongo-java-driver升级到3.2版本时,特定的集合开始破坏。
我们最终不得不对该集合中的所有记录进行更新,类似于此
db.columnDefinition.update({field: null}, {$unset: {field: 1}}, {multi: true})
一旦没有包含“null”的记录被映射到对象中的bean,一切都开始正常。
我们在集合中没有一个“未定义”,但我只能猜测它也会导致问题。
我们有相同的BsonUndefined异常,即使问题与undefined无关。
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.bson.BsonUndefined] to type [java.lang.String]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:313) ~[spring-core-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176) ~[spring-core-4.3.1.RELEASE.jar:4.3.1.RELEASE]
编辑:同样在我们的情况下,我们注意到它似乎并不总是一个问题。我们有其他集合,我们直接访问它们,它们有“null”字段,可以很好地读取。它似乎与从DBRef风格中提取的任何东西有关。在我的情况下,报告将DBRef添加到列,因此读取报告时会因为列中包含一个空字段而崩溃。但是报告本身的字段为空但不会中断。
这是spring-data 1.9.2,spring 4.3.1,mongo 3.2.2
我们最近遇到了这个问题,所以我将研究结果放在这里以防其他人也遇到这个问题。
这是Spring Data MongoDB中的一个已知错误:
https://jira.spring.io/browse/DATAMONGO-1439
该链接的解决方法是添加一个显式转换器,用于从BsonUndefined
转换为null
。例如,使用Java 8:
@ReadingConverter
public class BsonUndefinedToNullObjectConverterFactory implements ConverterFactory<BsonUndefined, Object> {
@Override
public <T extends Object> Converter<BsonUndefined, T> getConverter(Class<T> targetType) {
return o -> null;
}
}
没有Lambda(Java 8之前版本):
@ReadingConverter
public class BsonUndefinedToNullObjectConverterFactory implements ConverterFactory<BsonUndefined, Object> {
@Override
public <T extends Object> Converter<BsonUndefined, T> getConverter(Class<T> targetType) {
return new Converter<BsonUndefined, T>() {
@Override
public T convert(BsonUndefined source) {
return null;
}
};
}
}
对于Java而言,该字段是否存在或具有空值并不重要,因此您也可以像上面的答案中一样替换它。但是,如果您真的想要匹配具有确切“未定义”值的字段,则只能在Mongo控制台中的JS中执行此操作。
在我的情况下,我想从对象中删除所有这些字段,因此执行正确检查和删除的函数将如下所示:
function unsetUndefined(obj) {
return Object.keys(obj).filter((k, i) => {
if(obj[k] === undefined) {
delete obj[k];
return true
}
return false;
}).length > 0;
}
后来将它们组合成可执行的Mongo Shell代码,它可能是这样的:
const collectionName = "...";
const query = {...};
function unsetUndefined(obj) {
return Object.keys(obj).some((k, i) => {
if(obj[k] === undefined) {
delete obj[k];
return true;
}
});
}
db.getCollection(collectionName).find(query).forEach(record =>{
const changed = unsetUndefined(record);
if(changed) {
db.getCollection(collectionName).save(record);
}
});