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

Validation fails if a new transaction is present [DATAREST-1040]

Open
#1,406 1 comment 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 31, 2020.

type: bug
Dominant language
Java
Stars
958
Forks
568
PR merge metrics
No merged PRs in 30d

Description

Petar Tahchiev opened DATAREST-1040 and commented

Hello,

I have a JPA entity like this:

class Product {
   @Id
   private long id;

   @NotNull
   private String test;
}

that has a javax.validation.@NotNull annotation. I want to write a test-case that asserts a validation message is returned if I try to persist this entity and no test property is given.
So my test-case is the following:

mockMvc.perform(post("http://localhost:8080/productEntities/").content("{ \"id\" : \"1\"}").accept(
                MediaType.APPLICATION_JSON_UTF8_VALUE).contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)).andDo(print()).andExpect(
                status().isInternalServerError()).andExpect(jsonPath("$.errors", hasSize(2))).andExpect(
                jsonPath("$.errors[0].entity", is("ProductEntity"))).andExpect(
                jsonPath("$.errors[0].message", is("may not be null"))).andExpect(
                jsonPath("$.errors[0].invalidValue", is(nullValue()))).andExpect(jsonPath("$.errors[0].property", is("test")));

When I run my test it fails with an error, saying javax.persistence.RollbackException: Error while committing the transaction.

So I try surrounding the test with a Transaction. And then funny thing happens:

  • boot 1.4.0 (Hopper SR2) returns 500 but no json response body.
  • boot 1.4.1, boot 1.4.2, boot 1.4.3, boot 1.4.4, boot 1.4.5, boot 1.4.6-SNAPSHOT and boot 2.0.0-SNAPSHOT return 201 (created)!!!!!
MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /productEntities/
       Parameters = {}
          Headers = {Accept=[application/json;charset=UTF-8], Content-Type=[application/json;charset=UTF-8]}

Handler:
             Type = org.springframework.data.rest.webmvc.RepositoryEntityController
           Method = public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = {Location=[http://localhost:8080/productEntities/1], Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {
  "approvalStatus" : null,
  "title" : { },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/productEntities/1"
    },
    "productEntity" : {
      "href" : "http://localhost:8080/productEntities/1"
    }
  }
}
    Forwarded URL = null
   Redirected URL = http://localhost:8080/productEntities/1
          Cookies = []

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /productEntities/
       Parameters = {}
          Headers = {Accept=[application/json;charset=UTF-8], Content-Type=[application/json;charset=UTF-8]}

Handler:
             Type = org.springframework.data.rest.webmvc.RepositoryEntityController
           Method = public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = {Location=[http://localhost:8080/productEntities/1], Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {
  "approvalStatus" : null,
  "title" : { },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/productEntities/1"
    },
    "productEntity" : {
      "href" : "http://localhost:8080/productEntities/1"
    }
  }
}
    Forwarded URL = null
   Redirected URL = http://localhost:8080/productEntities/1
          Cookies = []
Tests run: 2, Failures: 1, Errors: 0, Skipped: 1, Time elapsed: 4.263 sec <<< FAILURE! - in com.example.DemoRestSerializationProblemApplicationTests
testCreate(com.example.DemoRestSerializationProblemApplicationTests)  Time elapsed: 0.239 sec  <<< FAILURE!
java.lang.AssertionError: Status expected:<500> but was:<201>
	at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
	at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
	at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
	at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
	at com.example.DemoRestSerializationProblemApplicationTests$1.doInTransactionWithoutResult(DemoRestSerializationProblemApplicationTests.java:68)
	at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:34)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
	at com.example.DemoRestSerializationProblemApplicationTests.testCreate(DemoRestSerializationProblemApplicationTests.java:63)

What's even weirder is that if the id property was generated by hibernate the response contains generated id!

I'll provide a test project soon


No further details from DATAREST-1040

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.