问题
I have an existing mongo database in which ids (_id) are persisted as plain Strings.. This is sample data in Mongo DB:
{
"_id" : "528bb0e2e4b0442f1479f1b4",
"schoolId" : "URDLKYLFJXLWJGR193778316742298",
"surname" : "Lewis",
"admissionNumber" : "0347",
"firstName" : "Martins"
}
I have a Java object which is of the form:
public class Student {
@Id
private String id;
private String schoolId;
private String surname;
private String admissionNumber;
private String firstName;
}
With Getters and Setters
I also have a repository:
public interface StudentRepository extends MongoRepository<Student, String> {
Student findOneBySurname(String surname);
Student findOneById(String id);
Student findOneBySurnameAndFirstName(String surname, String firstName);
}
When I do a studentRepository.findAll() I am able to get all the Students in the database with all their fields populated correctly.
When I do a studentRepository.findOne("528bb0e2e4b0442f1479f1b4") or a studentRepository.findOneById)"528bb0e2e4b0442f1479f1b4") it returns null
When I do a debug of the mongo query I can see that it is calling:
2015-11-19 16:06:32.327 DEBUG 87081 --- [ main] o.s.data.mongodb.core.MongoTemplate : findOne using query: { "id" : "528bb0e2e4b0442f1479f1b4"} fields: null for class: class com.ad.josh.domain.Student in collection: Student
2015-11-19 16:06:32.331 DEBUG 87081 --- [ main] o.s.data.mongodb.core.MongoDbUtils : Getting Mongo Database name=[joshdb]
2015-11-19 16:06:32.333 DEBUG 87081 --- [ main] o.s.data.mongodb.core.MongoTemplate : findOne using query: { "_id" : { "$oid" : "528bb0e2e4b0442f1479f1b4"}} in db.collection: josh.Student
Typically I can see that it is still querying with Object Id and not a plain String.
I have seen suggestions to:
Create a Converter which throws a RuntimeException
But this does not work; it just throws a RuntimeException.
Any suggestions on how to use Spring Data to access a Mongo database where the Ids are defined as String already (in an existing database) would be really appreciated.
回答1:
I think the problem here is a wrong "_id" format and that is why Mongo cannot recognize any object with such id. It should looks like ObjectId("528bb0e2e4b0442f1479f1b4"), not plain String type.
{
"_id" : ObjectId("528bb0e2e4b0442f1479f1b4"),
"schoolId" : "URDLKYLFJXLWJGR193778316742298",
"surname" : "Lewis",
"admissionNumber" : "0347",
"firstName" : "Martins"
}
So if you have imported .json with existing data to mongo you need to change id:
"_id": {$oid:"528bb0e2e4b0442f1479f1b4"},
And it should be converted to correct format.
Hope it can help someone.
回答2:
You can use different MongoTemplate
per repository as described here: Configure Multiple MongoDB repositories with Spring Data Mongo
In the repository that you don't want the conversion from String to ObjectId you have to use mongoTemplate that will lack ObjectIdToStringConverter
回答3:
A workaround that could work is to create your own converter for ObjectId.
You can customize the mongo mapper by supplying a @Bean of type MappingMongoConverter
@Configuration
public class MongoConfig {
@Bean
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(new MyObjectIdConverter());
return new CustomConversions(converters);
}
@Bean
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
try {
mappingConverter.setCustomConversions(customConversions());
}
catch (NoSuchBeanDefinitionException ignore) {}
// Don't save _class to mongo
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingConverter;
}
}
来源:https://stackoverflow.com/questions/33809010/how-to-use-mongo-with-spring-data-without-objectid