spring CustomConverter不适用于ReactiveMongoTemplate

bjg7j2ky  于 2024-01-05  发布在  Spring
关注(0)|答案(1)|浏览(168)

你好,Spring社区,
我有一个带有Mongo DB的Sping Boot 3应用程序。我使用Spring Data Mongo Reactive与数据库通信,除了这个问题,它工作得很好。
我有一个属性,我想封装与另一个类,但我需要相同的数据库结构的兼容性。

  1. @Data
  2. @Builder
  3. @RequiredArgsConstructor
  4. @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
  5. public class TestType {
  6. String value;
  7. }

个字符
如果不使用转换器编写,则此代码将生成以下文档:

  1. {
  2. "id": someID,
  3. "data": {},
  4. "testType":{"value":"payload"}
  5. }


但我需要它看起来像这样:

  1. {
  2. "id": someID,
  3. "data": {},
  4. "testType":"payload"
  5. }


所以我添加了两个CustomConverters,并添加了一个bean来提供mongoCustomConversions:

  1. @WritingConverter
  2. public class TestTypeStringConverter implements Converter<TestType, String> {
  3. @Override
  4. public String convert(TestType source) {
  5. return source.getValue();
  6. }
  7. }
  1. @ReadingConverter
  2. public class StringTestTypeConverter implements Converter<String, TestType> {
  3. @Override
  4. public TestType convert(@NonNull String source) {
  5. return new TestType(source);
  6. }
  7. }
  1. @Bean
  2. public MongoCustomConversions mongoCustomConversions() {
  3. return new MongoCustomConversions(List.of(
  4. new TestTypeStringConverter(),
  5. new StringTestTypeConverter()
  6. ));
  7. }

我使用mongoTemplate将我的更改写入数据库:

  1. private UpdateOneModel<Document> createUpdate(Entity newEntity) {
  2. var query = new Query().addCriteria(new Criteria(UNDERSCORE_ID).is(newEntity.getId()));
  3. var updateVehicle = new Update();
  4. var options = new UpdateOptions();
  5. options.upsert(true);
  6. updateVehicle.set(Entity.Fields.data, newEntity.getData());
  7. updateVehicle.set(Entity.Fields.testType, newEntity.getTestType());
  8. return new UpdateOneModel<>(query.getQueryObject(), updateVehicle.getUpdateObject(), options);
  9. }
  1. private Mono<BulkWriteResult> execute(String collectionName, UpdateOneModel<Document> updateModelList) {
  2. return reactiveMongoTemplate.getCollection(collectionName)
  3. .flatMap(c -> Mono.from(c.bulkWrite(List.of(updateModelList))));
  4. }

但是我的对象仍然被写为没有转换器。
MongoTemplate确认mongoTemplate包含我的转换器的示例。两者都分别列在转换器和writing-和readingPairs中。我尝试更改数据库,但也没有改变任何东西。在这一点上,我已经没有主意了。
我做错了什么?
感谢您的支持。

y1aodyip

y1aodyip1#

要执行upsert,您没有以正确的方式使用Spring。相反,您正在从com.mongodb包中调用bulkWrite方法。您正确定义的转换器是SpringData Mongo中的Spring概念。我使用了相同的reactiveMongoTemplate,但使用了SpringData Mongo中的upsert方法,它按预期工作。
我在这里做了一个提交的例子:https://github.com/sbernardo/spring-issues-examples/tree/main/sof-questions-77612149
无论如何,你仍然可以使用你目前的方法进行批量操作(你可以在我的代码库中找到这段代码):

  1. var entity = new Entity(UUID.fromString("7f6a35fb-a449-4e31-b9c1-7592cc969d83"), new TestType("HelloValue"));
  2. Update update = new Update();
  3. update.set(Entity.Fields.testType, entity.getTestType());
  4. update.set("field2", "otherFieldValue");
  5. return reactiveMongoTemplate
  6. .bulkOps(BulkOperations.BulkMode.UNORDERED, Entity.class)
  7. .upsert(Query.query(new Criteria(UNDERSCORE_ID).is(entity.getId())), update)
  8. .execute()
  9. .block()
  10. .toString();

字符串
我用的是spring-boot 3.2.0和java 21。

展开查看全部

相关问题