1

I have a pretty simple relationship where I have a Person entity with a @OneToOne mapping to a PersonAttributes entity.

I have a PersonRepository as such:

@Transactional(propagation = Propagation.REQUIRED)
public interface PersonRepository extends JpaRepository<Person, BigDecimal>, JpaSpecificationExecutor<Person> {
}

If I write a test against the repository where I update both the Person and the related PersonAttributes entity everything gets saved fine.

If I write the same test "putting" the updates to "/api/persons/{theId}" only the Person entity gets updated, the PersonAttributes entity does not.

I've done the same thing through the actual client application ( with AngularJS ) and still only the Person gets updated.

This test works:

@Test
public void testUpdatePersonData() throws Exception {       
    Person person = personRepository.findOne(new BigDecimal(411));
    assertNotNull( person );
    assertFalse(person.getPersonData().getLastName().equalsIgnoreCase("ZZZ"));

    person.setFormerSsn("dummySSN");
    person.getPersonData().setLastName("ZZZ");

    personRepository.saveAndFlush(person);

    Person updatedPerson = personRepository.findOne(new BigDecimal(411));

    assertEquals( "dummySSN", updatedPerson.getFormerSsn() );
    assertEquals( "ZZZ", updatedPerson.getPersonData().getLastName() );
}

This test does not work:

@Test
public void testUpdatePersonData() throws Exception {
    ObjectMapper mapper = new ObjectMapper();

    MvcResult result = mockMvc.perform(get("/api/persons/411")).andReturn();
    MockHttpServletResponse response = result.getResponse();
    byte [] content = response.getContentAsByteArray();

    // Convert from JSON to object
    Person person = mapper.readValue(content, Person.class);
    assertNotNull( person );
    assertFalse(person.getPersonData().getLastName().equalsIgnoreCase("ZZZ"));

    person.setFormerSsn("dummySSN");
    person.getPersonData().setLastName("ZZZ");

    String json = mapper.writeValueAsString(person);

    result = mockMvc.perform(put( "/api/persons/411")
            .content(json).contentType(MediaType.APPLICATION_JSON)).andReturn();
    assertNotNull(result);

    assertEquals( 204, result.getResponse().getStatus() );

    personRepository.flush();

    result = mockMvc.perform(get("/api/persons/411")).andReturn();
    response = result.getResponse();
    content = response.getContentAsByteArray();

    Person updatedPerson = mapper.readValue(content, Person.class);
    assertNotNull( updatedPerson );

    assertEquals( "812818181", updatedPerson.getFormerSsn() );

    // This seems to be a bug
    // Refer to: http://stackoverflow.com/questions/24699480/spring-data-rest-onetoone-not-saving-the-relationship-updated-entity
//      assertEquals( "ZZZ", updatedPerson.getPersonData().getLastName() );
}

Thoughts?

Thanks,

Cory.

Cory D
  • 31
  • 2
  • why `personRepositoryService.flush()` in your working test? – Stackee007 Jul 11 '14 at 16:15
  • What does "not work" mean? Are you seeing an exception? does an assertion fail? What is a personRepositoryService? Is your test running in a transaction? If so, the service might not be seeing the results yet. – Oliver Drotbohm Jul 11 '14 at 16:39
  • Not working means the last assert fails ( the one that is commented out ). The personRepositoryService is just a service that uses the personRepository. I changed that over to just personRepository. – Cory D Jul 11 '14 at 16:46
  • I updated the code to just use the personRepository in the tests so to get rid of confusion. Same behavior. We are using spring-data-rest 2.1.0. – Cory D Jul 11 '14 at 16:54
  • I think the test case is somewhat invalid. `findOne(…)` might be hitting the first level cache of the `EntityManager`. A more idiomatic way of verifying the change would be an additional `GET`, wouldn't it? – Oliver Drotbohm Jul 11 '14 at 17:57
  • Thanks. Yes, I updated the test to read the Person back with a GET instead of the findOne(...). Still the same results. What it comes down to is the flush() is not running the update for the related OneToOne "PersonData" entity. Only the Person update is executed. – Cory D Jul 14 '14 at 12:37
  • Have you tried using PATCH instead of PUT? – zachariahyoung Sep 26 '14 at 12:16

0 Answers0