JsonIgnoreProperties not working with spring boot - spring-boot

Currently, the Spring Boot sample application is created normally. In the request, if there are any unknown fields coming, then we need to throw an error.
For this the #JsonIgnoreProperties(ignoreUnknown = false) annotation is being used. However, when I am accessing the URL, it is not working.
Please find code snippet as follows:
#RestController #RequestMapping(value = "/")
#JsonIgnoreProperties(ignoreUnknown = false) public class
UserController {
private final Logger LOG = LoggerFactory.getLogger(getClass());
private final UserRepository userRepository;
private final UserDAL userDAL;
public UserController(UserRepository userRepository, UserDAL userDAL){
this.userRepository = userRepository;
this.userDAL = userDAL;
}
#RequestMapping(
value = "/create", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public User addNewUsers(#RequestBody #Valid User user)
throws JsonProcessingException {
LOG.info("Saving user.");
CardInfo cardInfo = new CardInfo();
cardInfo.setCardId("12345678901");
user.setCardInfo(cardInfo);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(cardInfo);
user.setCardInfo1(jsonString);
userDAL.getAllUsers();
return userRepository.save(user);
}
Please find sample Pom as follows:
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.journaldev.spring</groupId>
<artifactId>spring-boot-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-mongodb</name>
<description>Spring Boot MongoDB Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

You have at least 3 options:
Put #JsonIgnoreProperties on a class you deserialize, and not in Spring controller.
However, I see that the class you want to deserialize is com.journaldev.bootifulmongodb.model.User so, most probably, you can't modify it.
Configure your ObjectMapper instance:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
Customize Spring Boot's Jackson Object Mapper - by setting a correct environment property:
spring.jackson.deserialization.fail-on-unknown-properties=true
For further information, please refer to section 76.3 of Spring Boot's reference.

Related

How to use Spring's BackendIdConverter?

I have an entity named VendorProductMapping with embedded primary key. Hence I want to use BackendIdConverter to convert the embedded primary key to string and vice-versa.
I followed a few posts on stackoverflow and learnt that I need to use BackendIdConverter.
I created the following class:
public class VendorProductMappingIdConverter implements BackendIdConverter {
#Override
public Serializable fromRequestId(String id, Class<?> entityType) {
--
}
#Override
public String toRequestId(Serializable source, Class<?> entityType) {
--
}
#Override
public boolean supports(Class<?> type) {
--
}
}
The very first line gives me an error saying
Cannot resolve symbol 'BackendIdConverter'
Do I explicitly need to create a BackendIdConverter interface ?
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>UI</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>UI</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-validation</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EDIT:
Now that I've written a converter class, how do I use this ?
I need to send the primary key of VendorProductMapping class (i.e, VendorProductMappingPk) may be in an anchor tag. The error I see is
Failed to convert value of type 'java.lang.String' to required type 'com.example.UI.entity.VendorProductMappingPk'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.UI.entity.VendorProductMappingPk': no matching editors or conversion strategy found
BackendIdConverter is part of Spring Boot Data REST, so try adding the following dependency. However, I am not sure this is what you need for your case.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
I would say you need a JPA converter to achieve this:
#Converter
public class PersonNameConverter implements AttributeConverter<YourEmbeddedPrimaryKeyClass, String> {
#Override
public String convertToDatabaseColumn(YourEmbeddedPrimaryKeyClass id) {
// your conversion to String logic
}
#Override
public YourEmbeddedPrimaryKeyClass convertToEntityAttribute(String id) {
// your conversion to YourEmbeddedPrimaryKeyClass logic
}
}
Then you can configure this converter in your model:
#Entity
#IdClass(PK.class)
public class YourClass {
#Id
private YourEmbeddedPrimaryKeyClass id;
...
}
public class PK implements Serializable {
#Column(name = "MY_ID_FIELD")
#Convert(converter = IdConverter.class)
private YourEmbeddedPrimaryKeyClass id;
}
You can check additional details at https://www.baeldung.com/jpa-attribute-converters.

Wire Mock Stub Response body is not read by Spring Boot

I am creating a Spring Boot based Micro Service. This service will call a external service. I want to create Stub for that service to do my integration testing.
I have following configuration. But for some reason my while running my test class Stub is not properly created due to which my test is failing.
Test class
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"server.context-path=/app", "app.baseUrl=http://restapi-2.herokuapp.com"})
#AutoConfigureWireMock
#AutoConfigureMockMvc
class Restapi1ApplicationTests {
#Autowired
private ApiService apiService;
#Autowired
private RestTemplate restTemplate;
#Autowired
private ObjectMapper objectMapper;
#Autowired
private MockMvc mockMvc;
#Test
void contextLoads() {
}
#Test
void getMessage() throws Exception {
MockRestServiceServer mockRestServiceServer = WireMockRestServiceServer.with(this.restTemplate)
.baseUrl("http://restapi-2.herokuapp.com")
.stubs("classpath:/stubs/companyresponse.json").build();
CompanyDetail companyDetail = new CompanyDetail();
companyDetail.setCompanyName("Test");
mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/messages"))
.andExpect(status().isOk())
//.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("$.companyName").value("Test"));
//.andExpect(MockMvcResultMatchers.content().json(objectMapper.writeValueAsString(companyDetail)));
}
}
#RestController
public class Api_1_Controller {
private final ApiService apiService;
public Api_1_Controller(ApiService apiService) {
this.apiService = apiService;
}
#GetMapping(path = "/api/v1/messages")
public CompanyDetail getMessage(){
CompanyDetail companyDetail = apiService.getMessageFromApi();
return companyDetail;
}
}
#Service
public class ApiService {
private RestTemplate restTemplate;
public ApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public CompanyDetail getMessageFromApi(){
CompanyDetail companyDetail = null;
try{
companyDetail = restTemplate.getForEntity("http://restapi-2.herokuapp.com/companies",CompanyDetail.class).getBody();
}catch(Exception exception){
exception.printStackTrace();
throw exception;
}
return companyDetail;
}
}
#JsonInclude(value = JsonInclude.Include.NON_NULL)
public class CompanyDetail {
private String companyName;
//Getter and Setters
}
companyresponse.json is in below path
test/resources/stubs
{
"request": {
"urlPath": "/companies",
"method": "GET"
},
"response": {
"status": 200,
"jsonBody": {"companyName" : "Test"},
"headers": {
"Content-Type": "application/json"
}
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.heroku</groupId>
<artifactId>restapinew-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restapinew-1</name>
<description>restapi-1 project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<imageName>restapinew-1</imageName>
</configuration>
</plugin>
</plugins>
</build>
</project>
When Running this test case getting Response body as null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: No value at JSON path "$.companyName"
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:304)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:99)
Instead of JsonBody use body attribute, enclose your response (json response) in double quotes it may resolve the issue.

How to solveFailed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured

I am trying to run a SpringBootApplication in EC2, i have hosted the mysql in RDS. While i was trying in my local database it was working fine, but as soon as i shifted to Rds the application is giving me the error
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to auto-configure a DataSource: 'spring.datasource.url' is not
specified and no embedded datasource could be auto-configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
I have googled and tried to add some configuration in the application , but it is not working for me
Here i am posting the class which the application is mentioning
AppUserDAO
#Repository
#Transactional
public class AppUserDAO {
#Autowired
private EntityManager entityManager;
public AppUser findUserAccount(String userName) {
try {
String sql = "Select e from " + AppUser.class.getName() + " e " //
+ " Where e.userName = :userName ";
Query query = entityManager.createQuery(sql, AppUser.class);
query.setParameter("userName", userName);
return (AppUser) query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
}
AppRoleDAO
#Repository
#Transactional
public class AppRoleDAO {
#Autowired
private EntityManager entityManager;
public List<String> getRoleNames(Long userId) {
String sql = "Select ur.appRole.roleName from " + UserRole.class.getName() + " ur " //
+ " where ur.appUser.userId = :userId ";
Query query = this.entityManager.createQuery(sql, String.class);
query.setParameter("userId", userId);
return query.getResultList();
}
}
UserDetailsServiceImpl
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private AppUserDAO appUserDAO;
#Autowired
private AppRoleDAO appRoleDAO;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AppUser appUser=this.appUserDAO.findUserAccount(username);
if(appUser==null) {
System.out.println("User not found! "+username);
throw new UsernameNotFoundException("User "+username+" was not found in the database");
}
System.out.println("Found User :"+appUser);
List<String> roleNames=this.appRoleDAO.getRoleNames(appUser.getUserId());
List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
if(roleNames!=null) {
for(String role:roleNames){
GrantedAuthority authority = new SimpleGrantedAuthority(role);
grantList.add(authority);
}
}
UserDetails userDetails=(UserDetails)new User(appUser.getUserName(),appUser.getEncrytedPassword(),grantList);
return userDetails;
}
}
Application.properties
==============================
# DATABASE
# ===============================
spring.datasource.url=jdbc:mysql://myrdsinstance.ciswboatdreq.us-east-1.rds.amazonaws.com/rdsTest
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>SpringBootSecurityJPA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootSecurityJPA</name>
<description>Spring Boot +Spring Security + JPA + Remember
Me</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>org.o7planning.sbsecurity.SpringBootSecurityJpaApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Please help me to resolve this
Try this...
#PersistenceContext
private EntityManager entityManager;
EDIT
After Edits in Question
Failed to auto-configure a DataSource: 'spring.datasource.url' is notspecified and no embedded datasource could be auto-configured.
Reason: Failed to determine a suitable driver class
You have to mention the Driver of mysql in application.properties
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
(or)
spring.datasource.driverClassName=com.mysql.jdbc.Driver
Try to inject EntityManager dependency by constructor in your DAOs, not a field.
Moreover, you could also initialize your bean in your main Spring Boot application class, doing something like this:
#Bean
public EntityManager entityManager() {
return new EntityManager();
}

SpringBootTest does not roll back

(Although, there are plenty of similar questions I was not able to find the solution among them).
Why #Transactional annotation with #SpringBootTest works and rolls back nicely when I use DAO directly, but does not work when I test with TestRestTemplate?
tl;dr
Entity
#Entity
public class ToDoItem {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull #Column(unique = true)
private String title;
public ToDoItem() {}
public ToDoItem(String title) { this.title = title;}
// getters, setters, etc.
Repository
public interface ToDoRepository extends CrudRepository<ToDoItem, Long> {}
Application
#EnableTransactionManagement
#SpringBootApplication
#RestController
#RequestMapping("/todos")
public class ToDoApp {
public static void main(String[] args) {
SpringApplication.run(ToDoApp.class, args);
}
#Autowired
private ToDoRepository toDoRepository;
#GetMapping
ResponseEntity<?> fetchAll() { return ok(toDoRepository.findAll()); }
#PostMapping()
ResponseEntity<?> createNew(#RequestBody ToDoItem toDoItem) {
try {
toDoRepository.save(toDoItem);
return noContent().build();
} catch (Exception e) {
return badRequest().body(e.getMessage());
}
}
}
Now I create two tests which do basically the same: store some to-do items in in-memory database and check if size has increased:
Repository test
#ExtendWith(SpringExtension.class)
#SpringBootTest
#Transactional
class ToDoRepoTests {
#Autowired
private ToDoRepository toDoRepository;
#Test
void when_adding_one_item_then_success() {
toDoRepository.save(new ToDoItem("Run tests"));
assertThat(toDoRepository.findAll()).hasSize(1);
}
#Test
void when_adding_two_items_then_success() {
toDoRepository.saveAll(List.of(
new ToDoItem("Run tests"), new ToDoItem("Deploy to prod")));
assertThat(toDoRepository.findAll()).hasSize(2);
}
}
Then I create similar test that does exactly the same thing but via REST API (This one does not work and fails with Unique index or primary key violation):
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = ToDoApp.class, webEnvironment = WebEnvironment.RANDOM_PORT)
#Transactional
class ToDoControllerTests {
#LocalServerPort
private int localServerPort;
private TestRestTemplate testRestTemplate;
#BeforeEach
void setUp() {
testRestTemplate = new TestRestTemplate(new RestTemplateBuilder()
.rootUri("http://localhost:" + localServerPort));
}
#Test
void when_adding_one_item_then_success() {
// when
createToDo(new ToDoItem("Walk the dog"));
var allItems = fetchAllTodos();
// then
assertThat(allItems).hasSize(1);
}
#Test
void when_adding_two_items_then_success() {
// when
createToDo(new ToDoItem("Walk the dog"));
createToDo(new ToDoItem("Clean the kitchen"));
var allItems = fetchAllTodos();
// then
assertThat(allItems).hasSize(2);
}
private void createToDo(ToDoItem entity) {
var headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
var response = testRestTemplate.postForEntity("/todos", new HttpEntity<>(entity, headers), String.class);
assertThat(response.getStatusCode()).isEqualTo(NO_CONTENT);
}
private List<ToDoItem> fetchAllTodos() {
return Arrays.asList(testRestTemplate.getForObject("/todos", ToDoItem[].class));
}
}
And here is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>foo.bar</groupId>
<artifactId>todo-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>To-Do App</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Please, help me to understand, what I am doing wrong.
When you call the API using the RESTTemplate it crosses the boundary of the local transaction management and becomes as distributed transaction. There is not mechanism available for spring to roll back that call to the rest API. Although in your example the target system is the same application, it need not be so. It could be an external application that is not aware of the transactional boundaries that you have set in your test.

Rest template getForObject() mapping only camel case fields

Having a rest web service that returns the below xml response.
Person>
<ttId>1408</ttId>
<FirstName>RAJ</FirstName>
<NationalityValue>INDIAN</NationalityValue>
<Sex>Male</Sex>
</Person>
This is the dto
import java.io.Serializable;
import java.util.Date;
public class PersonInfoDto implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long ttId;
private String NationalityValue;
private String Sex;
private String FirstName;
//getters and setters
}
Using Spring Boot, When I try to consume using code it returns only one value(which is in camel case). Do I need to add any Naming strategy to make it work ?
String uri = apiPath;
RestTemplate restTemplate = new RestTemplate();
PersonInfoDto personInfoDto = restTemplate.getForObject(uri, PersonInfoDto.class);
//Here the object will contain only one value
ttId = 1408
rest values are returns null.
Is there any dependency is required for this ?
This is pom file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>msa</groupId>
<artifactId>MQA</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>MQA</name>
<description>MQA project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<orika-core.version>1.4.6</orika-core.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Oracle JDBC driver -->
<!-- https://mvnrepository.com/artifact/com.oracle/ojdbc14 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Orika -->
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>${orika-core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
You should use #XmlElement. Try this
public class PersonInfoDto implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long ttId;
#XmlElement(name = "NationalityValue")
private String nationalityValue;
#XmlElement(name = "Sex")
private String sex;
#XmlElement(name = "FirstName")
private String firstName;
//getters and setters
}
Another option is to write custom Http Message Converter. Have a look at this http://www.baeldung.com/spring-httpmessageconverter-rest
Removed the below entry from the pom.xml. It worked.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Resources