【问题标题】:Java - MongoDB mapping object keys with dashes (Message-Id) to dots (Message.Id). Spring Data MongoDBJava - MongoDB 将带有破折号 (Message-Id) 的对象键映射到点 (Message.Id)。春季数据 MongoDB
【发布时间】:2015-12-04 14:03:26
【问题描述】:

我在将文档中的 MongoDB 对象映射到 Java 哈希映射时遇到了一个奇怪的问题。

如果我将一个带有HashMap 的对象(如("Message-Id" => "something"))存储到某个集合并再次从数据库中获取它,则结果对象将具有HashMap 和这个("Message.Id" => "something")

我在 Spring Boot 应用程序中使用 Spring Data MongoDB。

单元测试:

package com.mailor.app.data.mapping.bugs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

import java.util.HashMap;
import java.util.Optional;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.google.common.collect.Maps;
import com.mailor.app.data.DataConfig;
import com.mailor.app.data.TestDataConfig;
import com.mailor.app.data.constants.HeaderParams;
import com.mailor.app.data.mapping.entity.MessageIdTestEntity;

/**
 * @author jakob
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { DataConfig.class, TestDataConfig.class })
public class MessageIdDotDashTest {

    @Autowired
    private MongoTemplate template;

    @Test
    public void messageIdDotOrDashTest() {
        //HeaderParams.MESSAGE_ID = Message-Id
        dotOrDashInKeyTest(HeaderParams.MESSAGE_ID);
    }

    @Test
    public void contentTypeDotOrDashTest() {
        dotOrDashInKeyTest("Content-Type");
    }

    @Test
    public void somethingDotOrDashTest() {
        dotOrDashInKeyTest("Something-with-dashes");
    }

    @Test
    public void hashMapSetOnKeyWithDashTest() {
        HashMap<String, String> testMap = Maps.newHashMap();
        testMap.put(HeaderParams.MESSAGE_ID, "something");
        assertEquals("something", testMap.get(HeaderParams.MESSAGE_ID));
    }

    private void dotOrDashInKeyTest(String key) {
        String messageId = "some kind of message id";
        MessageIdTestEntity testEntity = new MessageIdTestEntity();
        testEntity.getHeaders().put(key, messageId);
        template.save(testEntity);

        Optional<MessageIdTestEntity> testEntityFromDB = Optional.ofNullable(template.findOne(query(where("code").is(testEntity.getCode())), MessageIdTestEntity.class));
        assertTrue(testEntityFromDB.isPresent());
        assertNotNull(testEntityFromDB.get().getHeaders().get(key)); // THIS FAILING, header key is Message.Id not Message-Id
        assertEquals(messageId, testEntityFromDB.get().getHeaders().get(key));
    }
}

测试对象:

package com.mailor.app.data.mapping.entity;

import java.util.HashMap;
import java.util.UUID;

import com.google.common.collect.Maps;

/**
 * @author jakob
 *
 */
public class MessageIdTestEntity {

    private String code = UUID.randomUUID().toString();

    private HashMap<String, String> headers = Maps.newHashMap();

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @return the headers
     */
    public HashMap<String, String> getHeaders() {
        return headers;
    }

    /**
     * @param headers
     *            the headers to set
     */
    public void setHeaders(HashMap<String, String> headers) {
        this.headers = headers;
    }

}

【问题讨论】:

    标签: java spring mongodb spring-mvc


    【解决方案1】:

    已通过使用修复

    ((MappingMongoConverter)
    mongoTemplate.getConverter()).setMapKeyDotReplacement("#dot#");
    

    说明

    我们在 mongo db 对象键中使用标准符号来替换点(点是禁止的),它使用破折号 (-) 作为点 (.) 的替换。

    ((MappingMongoConverter)
    mongoTemplate.getConverter()).setMapKeyDotReplacement("-");
    

    但是,如果您现在有一个带有破折号的对象键,MongoDB 映射器将破折号替换为点,因为他不知道您之前是否使用破折号或点保存键。 出于这个原因,我们必须使用唯一的点键替换,如#dot# 或一些罕见的东西,你永远不会在对象键名中使用的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-28
      • 2014-12-21
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多