MongoDB-Escape dots'。'在地图键]

时间:2016-09-30 06:26:41

标签: spring mongodb

地图键codeofproduct包含点,但未配置替换!确保地图键首先不包含点或配置适当的替换!

  

org.springframework.data.mapping.model.MappingException:映射键foo.bar.key包含点但未配置替换!确保地图键首先不包含点或配置适当的替换!       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.potentiallyEscapeMapKey(MappingMongoConverter.java:622)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeMapInternal(MappingMongoConverter.java:586)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.createMap(MappingMongoConverter.java:517)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:424)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:386)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:373)       在org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:451)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:386)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:373)       在org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:451)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:386)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter $ 3.doWithPersistentProperty(MappingMongoConverter.java:373)       在org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:345)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:310)       在org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:77)       在org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:859)       在org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:806)       在org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:794)

当我们尝试插入值时,会发生这种情况。我们怎样解决这个问题?

这是我的班级

@Configuration
@EnableMongoRepositories("net.ooo.hepsiburada.**.repository")
@Profile(Constants.SPRING_PROFILE_CLOUD)
public class CloudMongoDbConfiguration extends AbstractMongoConfiguration  {

    private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);

    @Inject
    private MongoDbFactory mongoDbFactory;

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() {
        return new ValidatingMongoEventListener(validator());
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }

    @Bean
    public CustomConversions customConversions() {
        List<Converter<?, ?>> converterList = new ArrayList<>();;
        converterList.add(DateToZonedDateTimeConverter.INSTANCE);
        converterList.add(ZonedDateTimeToDateConverter.INSTANCE);
        converterList.add(DateToLocalDateConverter.INSTANCE);
        converterList.add(LocalDateToDateConverter.INSTANCE);
        converterList.add(DateToLocalDateTimeConverter.INSTANCE);
        converterList.add(LocalDateTimeToDateConverter.INSTANCE);
        return new CustomConversions(converterList);
    }

    @Override
    protected String getDatabaseName() {
        return mongoDbFactory.getDb().getName();
    }

    @Override
    public Mongo mongo() throws Exception {
        return mongoDbFactory().getDb().getMongo();
    }
}

3 个答案:

答案 0 :(得分:6)

使用Spring Data MongoDB时,您会得到一个:org.springframework.data.mongodb.core.convert.MappingMongoConverter的实例,默认情况下mapKeyDotReplacement设置为null - 这就是您获得异常的原因。

您需要创建自己的org.springframework.data.mongodb.core.convert.MappingMongoConverter实例,或者只需使用其提供者setter方法修改现有实例:

/**
 * Configure the characters dots potentially contained in a {@link Map} shall be replaced with. By default we don't do
 * any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire
 * object to fail. If further customization of the translation is needed, have a look at
 * {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}.
 * 
 * @param mapKeyDotReplacement the mapKeyDotReplacement to set
 */
public void setMapKeyDotReplacement(String mapKeyDotReplacement) {
    this.mapKeyDotReplacement = mapKeyDotReplacement;
}

在MongoDB中,dot始终被视为一个特殊字符,因此避免使用它很可能会在将来为您节省一些其他麻烦。

编辑: 要覆盖默认的MappingMongoConverter,请添加以下bean声明:

  @Bean
  public MappingMongoConverter mongoConverter(MongoDbFactory mongoFactory) throws Exception {
    DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoFactory);
    MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
    mongoConverter.setMapKeyDotReplacement(".");

    return mongoConverter;
  }

答案 1 :(得分:4)

我的例外:

IndexError                                Traceback (most recent call last)
<ipython-input-35-f0c57ab3748f> in <module>
----> 1 learn.fit(30,1e-2)

/mnt/c/fastai2/fastai2/learner.py in fit(self, n_epoch, lr, wd, cbs, reset_opt)
    191                         self.epoch=epoch;          self('begin_epoch')
    192                         self._do_epoch_train()
--> 193                         self._do_epoch_validate()
    194                     except CancelEpochException:   self('after_cancel_epoch')
    195                     finally:                       self('after_epoch')

/mnt/c/fastai2/fastai2/learner.py in _do_epoch_validate(self, ds_idx, dl)
    173             dl,old,has = change_attrs(dl, names, [False,False])
    174             self.dl = dl;                                    self('begin_validate')
--> 175             with torch.no_grad(): self.all_batches()
    176         except CancelValidException:                         self('after_cancel_validate')
    177         finally:

/mnt/c/fastai2/fastai2/learner.py in all_batches(self)
    141     def all_batches(self):
    142         self.n_iter = len(self.dl)
--> 143         for o in enumerate(self.dl): self.one_batch(*o)
    144 
    145     def one_batch(self, i, b):

/mnt/c/fastai2/fastai2/learner.py in one_batch(self, i, b)
    149             self.pred = self.model(*self.xb);                self('after_pred')
    150             if len(self.yb) == 0: return
--> 151             self.loss = self.loss_func(self.pred, *self.yb); self('after_loss')
    152             if not self.training: return
    153             self.loss.backward();                            self('after_backward')

/mnt/c/fastai2/fastai2/layers.py in __call__(self, inp, targ, **kwargs)
    291         if targ.dtype in [torch.int8, torch.int16, torch.int32]: targ = targ.long()
    292         if self.flatten: inp = inp.view(-1,inp.shape[-1]) if self.is_2d else inp.view(-1)
--> 293         return self.func.__call__(inp, targ.view(-1) if self.flatten else targ, **kwargs)
    294 
    295 # Cell

~/anaconda3/envs/py3/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    530             result = self._slow_forward(*input, **kwargs)
    531         else:
--> 532             result = self.forward(*input, **kwargs)
    533         for hook in self._forward_hooks.values():
    534             hook_result = hook(self, input, result)

~/anaconda3/envs/py3/lib/python3.6/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
    914     def forward(self, input, target):
    915         return F.cross_entropy(input, target, weight=self.weight,
--> 916                                ignore_index=self.ignore_index, reduction=self.reduction)
    917 
    918 

~/anaconda3/envs/py3/lib/python3.6/site-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction)
   2019     if size_average is not None or reduce is not None:
   2020         reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 2021     return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
   2022 
   2023 

~/anaconda3/envs/py3/lib/python3.6/site-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)
   1836                          .format(input.size(0), target.size(0)))
   1837     if dim == 2:
-> 1838         ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
   1839     elif dim == 4:
   1840         ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)

IndexError: Target -1 is out of bounds.

结尾处带点的字段:org.springframework.data.mapping.MappingException: Map key VAT Registration No. contains dots but no replacement was configured! Make sure map keys don't contain dots in the first place or configure an appropriate replacement!

这对我不起作用:

VAT Registration No.

这对我有用:

mongoConverter.setMapKeyDotReplacement(".");
mongoConverter.setMapKeyDotReplacement("_"); //this broke enum values for example VALUE_1 -> VALUE.1

完成课程:

mongoConverter.setMapKeyDotReplacement("-DOT")

答案 2 :(得分:0)

对于XML配置,以下内容非常有用。

注意:mongoConverter bean用于此目的。它将取代“。”用“_”

<bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />

<mongo:auditing mapping-context-ref="mappingContext"/>

<mongo:db-factory id="mongoDbFactory" mongo-ref="mongoClient" dbname="${mongo.dbname}"/>

<bean id ="mongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    <constructor-arg name="mappingContext" ref="mappingContext"/>
    <property name="mapKeyDotReplacement" value="_"></property>
</bean>

<mongo:mongo-client id="mongoClient" credentials="${mongo.credential}" >
    <mongo:client-options  connections-per-host="50" threads-allowed-to-block-for-connection-multiplier="5000" />
</mongo:mongo-client>

<!-- MongoDB Template -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    <constructor-arg name="mongoConverter" ref="mongoConverter"/>   
</bean>