spring 指示Sping Data MongoDB使用ObjectId和其类之间的正确Map

72qzrwbm  于 2022-12-17  发布在  Spring
关注(0)|答案(1)|浏览(107)

I cannot retrieve the 2nd level nested objects in Spring Data MongoDB
I have nested collection in MongoDB to retrieve with Spring. Imagine this schema

@Data
@Builder
@Document(collection = "emitted")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Emitter{

    @Id
    private String id;

    @Field("installation")
    @DocumentReference(lazy = true)
    private Installaton installation;

    // other fields
@Data
@Builder
@Document(collection = "installation")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Installation {

    @Id
    private String id;

    @Field("subject")
    @DocumentReference(lazy = true)
    private Subject subject;
    
    // other fields
@Data
@Builder
@Document(collection = "subject")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Subject {

    @Id
    private String id;

    // other fields

Plus, I have MapStruct to map nested object field to string, for the purpose of avoiding cyclic reference introducing the search by id of the collection:

@ObjectFactory
public <T> T map(@NonNull final String id, @TargetType Class<T> type) {
    return mongoTemplate.findById(id, type);
}

Everything works at first level, but at nested level I have this error:
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.bson.types.ObjectId] to type [com.package.collections.Subject] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1826) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1818) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1337) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1311) at org.springframework.data.mongodb.core.convert.MappingMongoConverter$DefaultConversionContext.convert(MappingMongoConverter.java:2371) at org.springframework.data.mongodb.core.convert.MappingMongoConverter$ConversionContext.convert(MappingMongoConverter.java:2174) at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1936) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:638) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:549) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:527) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:491) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:427) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:423) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:120) at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3326) at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2940) at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2618) at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2588) at org.springframework.data.mongodb.core.MongoTemplate.findById(MongoTemplate.java:922) at com.package.myapp.services.mapper.ReferenceMapper.map(ReferenceMapper.java:26) at com.package.myapp.services.mapper.InstallationMapperImpl.toEntity(InstallationMapperImpl.java:102)
When asking the conversion, the findById works correctly and retrieve the object and the nested one. It fails when the request is for 2nd level nested object, where the ObjectId is retrieved but cannot be converted and fails.

j9per5c4

j9per5c41#

我在回答我自己因为我找到了适合我问题的解决方案。
我只需要ID为的实体对象,所以我编写了一个转换器:

public class ObjectIdToSubjectConverter implements Converter<ObjectId, Subject> {
    @Override
    public Subject convert(ObjectId source) {
        return Subject.builder().id(source.toString()).build();
    }
}

并将其注册为bean:

@Configuration
public class MongoConfig {
    @Bean
    public MongoCustomConversions mongoCustomConversions() {
        return new MongoCustomConversions(Collections.singletonList(new ObjectIdToSubjectConverter());
    }
}

相关问题