spring-projects / spring-projects/spring-data-rest

JsonMappingException when POST and deserialize to a HashMap

Open
#103 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
958
Forks
568
PR merge metrics
No merged PRs in 30d

Description

Hi
I'm trying to create a new Document in my MongoDB using the DATA-REST-API but when the json contains data for the HashMap attribute, it fails with JsonMappingException: Can not deserialize instance of java.lang.String out of FIELD_NAME token

Using the default configuration (RepositoryRestMvcConfiguration)

Foo.java

@Document
public class Foo implements Serializable {
      @Id
      private String id;
      private String name;
      private HashMap<String, String> map = new HashMap<String, String>();
      // getters & setters omitted
}

FooRepository.java

public interface FooRepository extends MongoRepository<Foo, String> {}

FooTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration()
@ContextConfiguration()
public class FooTest {
    @Autowired private WebApplicationContext wac;
    @Autowired private FooRepository repo;
    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
     }

    @Test    
    // It works 
    public void testGET() throws Exception {
         repo.deleteAll();
         HashMap<String, String> map = new HashMap<String,String>();
         map.put("key1", "value1");
         map.put("key2", "value2");
         Foo foo = new Foo(); foo.setName("FooName"); foo.setMap(map);
         Foo saved = repo.save(foo);

         // test GET foo
         MvcResult result = this.mockMvc.perform(get("/foo/" + saved.getId())
          .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
          .andExpect(status().isOk())
          .andExpect(content().contentType("application/json;charset=UTF-8"))
          .andExpect(jsonPath("$.name").value(foo.getName()));
         String content = result.getResponse().getContentAsString();
         System.out.println( "result /foo/" + saved.getId() + ":\n" + content);

    }

    @Test 
    // It works :-)
    public void testPOST1() throws Exception {
        repo.deleteAll();
        String json = "{\"name\":\"testSimple\"}";
        this.mockMvc.perform(post("/foo")
            .contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))
            .content(json))
            .andExpect(status().is(201));
     }

    @Test 
    // It doesn't work :-( 
    public void testPOST2() throws Exception {
        repo.deleteAll();
        String json = "{\"name\":\"test\", \"map\":{\"key1\":\"value1\", \"key2\":\"value2\"}}"; 
       this.mockMvc.perform(post("/foo")
            .contentType(MediaType.parseMediaType("application/json;charset=UTF-8"))
            .content(json))
            .andExpect(status().is(201));
       }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with FooTest.java, especially testPOST2, and reproduce the POST through MockMvc using RepositoryRestMvcConfiguration; compare it with testPOST1 and the repository-backed GET. Trace the request into the map field in Foo.java and FooRepository.java, then confirm the nested HashMap JSON POST returns 201 and preserves both entries.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, mongodb, spring
Domain
api, backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.