Send JSON Object from Postman to Restful webservices - java

For exercise I'm trying to make a POST call on postman having the following classes but it always gives me an error that it cannot read the data.
The GET give me back the various users in the db and the commented POST where I go to create the new user manually (ie by setting the strings "blabla") works. I would like my POST to take a json object from the postman body
{
"username": "1",
"password": "2",
"email": "3"
}
and sending the request I enter the new user in the db. How can I do?
UserDB.java
public class UserDB {
public void insertUser(User user) {
EntityManager entityManager = JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
user.setUsername(user.getUsername());
user.setPassword(user.getPassword());
user.setEmail(user.getEmail());
entityManager.persist(user);
entityTransaction.commit();
}
User.java
#XmlRootElement(name = "user")
#XmlAccessorType(XmlAccessType.FIELD)
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private int user_id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
public User() {
}
public User(int user_id, String username, String password, String email) {
this.user_id = user_id;
this.username = username;
this.password = password;
this.email = email;
}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String passoword) {
this.password = passoword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
RestUser.java
#Path("/users")
public class RestUser {
private UserDB userDB;
public RestUser() {
this.userDB = new UserDB();
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public String getUsers_JSON() {
String listUser = null;
List<User> list = userDB.selectAllUsers();
Gson gson = new Gson();
listUser = gson.toJson(list);
return listUser;
}
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public String getUser_byid(#PathParam("id") int id) {
String u = null;
User user = userDB.selectUser_ID(id);
Gson gson = new Gson();
u = gson.toJson(user);
return u;
}
/*
#POST
#Produces(MediaType.APPLICATION_JSON)
public String message() {
String u = null;
Gson gson = new Gson();
User user = new User("user", "sss", "sss");
u = gson.toJson(user);
userDB.insertUser(user);
return u;
}
*/
#POST
#Path("/insert")
#Produces(MediaType.APPLICATION_JSON)
public void createUser(#QueryParam("username") String username,#QueryParam("password") String password,#QueryParam("email") String email) {
User newuser = new User(username, password, email);
userDB.insertUser(newuser);
}
}
I add my 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.exercises</groupId>
<artifactId>UserManagement</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.9.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.9.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.5</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>UserManagement</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
and my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>jerseyServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>net.java.webservice</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jerseyServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>

In your controller method createUser you defined three query parameters for the user attributes instead of using the request body to receive the user data.
If you want to receive the user object as JSON in the request body try this:
#POST
#Path("/insert")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public void createUser(User user) {
userDB.insertUser(user);
}
Note the #Consumes annotation. When a HTTP POST request is sent to /users/insert (you could also leave /insert out, see below) the createUser method will be called and the JSON document with the user details will be converted into a Java object of the type User.
You can simplify it to:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public void createUser(User user) {
userDB.insertUser(user);
}

Related

I type this code {"name":"upul","email":"upul#gmail.com"} in postman as a post request ,

but i got this error,
2021-02-05 12:19:08.944 WARN 8168 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present]
dependencies are,
<?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.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.sample</groupId>
<artifactId>springboot-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-test</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
** Repository is,**
package com.example.sample.springboottest.Model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class User {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
** Controllers are,**
package com.example.sample.springboottest.Controller;
import com.example.sample.springboottest.Model.User;
import com.example.sample.springboottest.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
#Controller
#RequestMapping(path = "/demo")
public class MainController {
#Autowired
private UserRepository userRepository;
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestParam String name, #RequestParam String email){
User n =new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAllUser(){
return userRepository.findAll();
}
}
** Properties are,**
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.open-in-view=true
spring.jpa.show-sql=true
Please help me to fix this,
Since you are using #ReuestParam you can't pass JSON like what you did.
In order to pass JSON format change #RequestParam to #RequestBody as below:
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestBody User user){
// User n =new User();
//
// n.setName(name);
// n.setEmail(email);
// userRepository.save(n);
userRepository.save(user);
return "Saved";
}
And postman result would be as below:
But if you need to use #RequestParam then pass query string as below:
localhost:8811/demo/add?name=upul&email=upul#gmail.com
It seems that you have mixed up #RequestParam with #RequestBody
You seem to want to POST a JSON object to your controller, in which case your method signature should be
public #ResponseBody String addNewUser(#RequestBody User user){
Required String parameter 'name' is not present
Method parameters annotated with #RequestParam are required by default. It looks like while you are calling the API, you are not passing the name query param.
Edit: In this case, we could be passing the user in the request body.

#MockMvc does not work with validation annotated with #Valid

None of these solutions helped here: Spring mockMvc doesn't consider validation in my test. Added all of these dependencies, nothing helps.
I use Spring Boot 2.1.2, pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</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>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.springtestdbunit</groupId>
<artifactId>spring-test-dbunit</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.5.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-matchers</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
I use standard hibernate validation '#NotNull':
#Entity
#Table(name="employee")
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Employee {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
#NotNull(message = "Please provide name")
#Column(name = "name")
private String name;
#Column(name = "role")
private String role;
public Employee() {}
public Employee(String name, String role) {
this.name = name;
this.role = role;
}
}
#RestController
#RequestMapping(EmployeeController.PATH)
public class EmployeeController {
public final static String PATH = "/employees";
#Autowired
private EmployeeService service;
#PostMapping("")
public Employee newEmployee(#RequestBody #Valid Employee newEmployee) {
return service.save(newEmployee);
}
}
#Service
public class EmployeeService {
#Autowired
private EmployeeRepository repository;
public Employee save(Employee entity) {
return getRepository().save(entity);
}
}
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Then I test my controller:
#RunWith(SpringRunner.class)
#SpringBootTest
#Transactional
#DatabaseSetup("/employee.xml")
#TestExecutionListeners({
TransactionalTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DbUnitTestExecutionListener.class
})
public class EmployeeControllerWebApplicationTest {
#Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
private static String employeeRouteWithParam = EmployeeController.PATH + "/{id}";
#Before
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.build();
}
#Test
public void create_WithoutName_ShouldThrowException() throws Exception {
String role = "admin";
Employee expectedEmployee = new Employee(null, role);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(expectedEmployee);
ResultActions resultActions = this.mockMvc.perform(post(PATH)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(json))
.andDo(print());
String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
System.out.println("content: " + contentAsString); // empty body
resultActions
.andExpect(status().isBadRequest())
.andExpect(jsonPath("error").exists()) // not exist!!!
.andExpect(jsonPath("timestamp").exists()); // not exist!!!
}
}
employee.xml:
<dataset>
<Employee id="1" name="John" role="admin"/>
<Employee id="2" name="Mike" role="user"/>
</dataset>
I can not understand why it does not work when I test through #MockMvc. What am i doing wrong? Status is correct, but there is no error content, empty response
But validation works if tested on a really running application, then everything works.

#NotNull constraint is not working in Spring Boot

I am using Spring Boot and the #NotNull is not working. When the name value is not provided the function runs fine.
#Entity
public class Employee implements Serializable{
#Id
//#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
//#Id
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#NotNull // not working
private String name;
private String phone;
}
the controller is
#Controller
public class URLController {
#Autowired
EmployeeServiceImpl empService;
#GetMapping({"/", "/index"})
public String index1(Model model){
model.addAttribute("employee",new Employee());
return "index";
}
#PostMapping("/result")
public String result(#Valid #ModelAttribute Employee employee){
System.out.print(employee.getName());
empService.save(employee);
return "result";
}
}
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.springs</groupId>
<artifactId>springs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springs</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
i am using the model attribute to get the employee object. the pom.xml file contains the hibernate validator dependency.
you must add #Valid annotaion in mapping part in your code for example
void addEmployee(#Valid Employee emp);
using this import "import javax.validation.Valid;"
Another note if you want to validate List you must make a wrapper list
Like
public class ValidList<E> implements List<E> {
#Valid
private List<E> list;}
And override all methods in it
Try modifying method like below to check details about errors.
#PostMapping("/result")
public String result(#Valid #ModelAttribute("employee") Employee employee, BindingResult bindingResult){
List<FieldError> errors = bindingResult.getFieldErrors();
for (FieldError error : errors ) {
System.out.println (error.getObjectName() + " - " +error.getDefaultMessage());
}
System.out.print(employee.getName());
empService.save(employee);
return "result";
}
If no error in bindingResult then refer notnull-constraint-not-working to troubleshoot further.

I am developing a sample application using spring rest api. But i get an error which i think it's related to jackson library

The error that i am getting:
Feb 04, 2016 9:20:52 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path
[/Example] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Unrecognized Type: [null]] with rootcause
java.lang.IllegalArgumentException: Unrecognized Type: [null]
atcom.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1109)
at com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:566)
at com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:602)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.getJavaType(AbstractJackson2HttpMessageConverter.java:311)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:249)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:153)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:165)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
User entity class:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
private String userName;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
The repository class:
#Repository
public class UserRepositoryImpl implements UserRepository {
#PersistenceContext
EntityManager entityManager;
public User findOne(long id) {
User user = entityManager.find(User.class, id);
return user;
}
public User createOne(User user) {
entityManager.persist(user);
return user;
}
public void deleteOne(long id) {
User user = findOne(id);
entityManager.remove(user);
}
public User updateOne(User user) {
return entityManager.merge(user);
}
#SuppressWarnings("unchecked")
public List<User> getAll() {
Query getAllQuery = entityManager.createNamedQuery("select user from User as user");
return (List<User>) getAllQuery.getResultList();
}
}
The service class:
#Service
#Transactional
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
public User createOne(User user) {
return userRepository.createOne(user);
}
public User updateOne(User user) {
return userRepository.updateOne(user);
}
public void deleteOne(long id) {
userRepository.deleteOne(id);
}
public User findOne(long id) {
System.out.println(id);
return userRepository.findOne(id);
}
public List<User> getAll() {
return userRepository.getAll();
}
}
The controller class:
#RestController
#RequestMapping(value = "/user")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(method = RequestMethod.POST)
public User createOne(#RequestBody User user) {
return userService.createOne(user);
}
#RequestMapping(method = RequestMethod.PUT)
public User updateOne(#RequestBody User user) {
return userService.updateOne(user);
}
#RequestMapping(path = "/{id}", method = RequestMethod.GET)
public User findOne(#PathVariable("id") long id) {
User user = userService.findOne(id);
return user;
}
#RequestMapping(value = "/{id}")
public void deleteOne(#PathVariable("id") Long id) {
userService.deleteOne(id);
}
}
The pom.xml file:
<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.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.adaptiv.exampleapp</groupId>
<artifactId>Example</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Example Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- Hibernate JPA -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<!-- MySql Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.1</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20151123</version>
</dependency>
</dependencies>
<build>
<finalName>Example</finalName>
</build>
</project>
Any idea why this error is occurring?
If i do the post request to UserController the User object is saved in db and then that error occur.
The configurations are done correctly i think, dispatcher serlvet is configured extending AbstractAnnotationConfigDispatcherServletInitializer
EDIT:
When i stop the server the following warning appears:
WARNING: The web application [Example] appears to have started a thread named
[Abandoned connection cleanup thread] but has failed to stop it.
This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(Unknown Source)
com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)
Please check your version of jackson dependecies on your pom.xml , try to change it :)
I got the same error with jackson data bind 2.7.1, updating the version to 2.7.1-1 solve the problem
I had same problem, I downgrade jackson-databind from 2.7.1 to 2.6.5 and(or) to 2.7.3 and it worked.

Spring-Data-Mongodb NoSuchMethodError when writing to db

I'm building a spring webapp using mongodb but recently I began having problems with writing to DB. The following stack trace is what I get.
SEVERE: Servlet.service() for servlet [DispatcherServlet] in context with path [/afcrowther_blog] threw exception [Handler processing failed; nested exception is java.lang.NoSuchMethodError: org.springframework.data.mongodb.core.mapping.MongoPersistentProperty.isWritable()Z] with root cause
java.lang.NoSuchMethodError: org.springframework.data.mongodb.core.mapping.MongoPersistentProperty.isWritable()Z
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:415)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:294)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:412)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:386)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:350)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:77)
at org.springframework.data.mongodb.core.MongoTemplate.toDbObject(MongoTemplate.java:732)
at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:714)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:672)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:663)
After reading up the most common cause of this seems to be dependency mismatches, but I'm not sure which dependencies are actually compatible with one another in that case.
Pom.xml
<spring.version>4.0.7.RELEASE</spring.version>
<jackson.version>1.9.2</jackson.version>
<spring.security.version>3.2.5.RELEASE</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>http://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
<build>
<finalName>afcrowther blog</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
</plugins>
</build>
These are mainly the latest release versions, although I changed spring framework to 4.0.7.Release to try and fix it, but I have also used 4.1.0.Release and the same exception occurs.
Thanks
EDIT: #Document Annotated class that throws the error, role set as a String until this problem is resolved
#Document(collection = "user")
public class UserModel{
#PersistenceConstructor
public UserModel(String id, String firstName, String surname, String email,
String password, String role) {
this.id = id;
this.firstName = firstName;
this.surname = surname;
this.email = email;
this.password = password;
this.role = role;
}
public UserModel(){
}
#Id
private String id;
#Field("firstName")
#Indexed
private String firstName;
#Field("surname")
private String surname;
#Field("email")
#Indexed(unique = true)
private String email;
#Field("password")
private String password;
#Field("role")
private String role;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole(){
return role;
}
public void setRole(String role){
this.role = role;
}
}
Update on the question, Upon changing to spring bom and spring data bom dependency management, the problem persisted.
However, removing the "#PersistenceConstructor" tag from the first constructor, and then switching around the order of the constructors fixed the issue. So the default constructor has to be first one in the file by the look of things. Not sure why, but there you go!

Categories

Resources