I'm trying to do a simple task. I've an API which is trying to create a post using userId and post desc as params. I'm initializing users in h2 DB directly using data.sql. In PostService, I'm trying to get user by userId using userRepo.findById(userId)
. The param is passed to the service from the request. However, I'm not getting any users. I'm getting a NullPointerException
. I checked the h2 db and I can see my users being present. Even the sout's are not working. Tried a few answers from internet, no luck as of yet.
Here's the code:
User.java
package com.interview.LLD.demo;
import javax.persistence.*;
@Entity
@Table(name = "User")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PostController.java
package com.interview.LLD.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/posts")
public class PostController {
@Autowired
private PostService postService;
@PostMapping("/create")
public Post createPost(@RequestBody CreatePostRequestBody createPostRequestBody) {
try {
return postService.createPost(createPostRequestBody.getDesc(), createPostRequestBody.getPostId());
}
catch (Exception e) {
System.out.println("e = " + e.getMessage());
return null;
}
}
@GetMapping("/getAllByUser")
public List<Post> getAllPostsByUser(@PathVariable Integer user) {
return postService.getAllPostsByUser(user);
}
}
PostService.java
package com.interview.LLD.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PostService {
@Autowired
private PostRepo postRepo;
@Autowired
private UserRepo userRepo;
public Post createPost(String postDesc, int userId) throws Exception {
System.out.println("no of users = " + userRepo.count());
userRepo.findAll().forEach(e -> System.out.print(e.getId() + " " + e.getName()));
User user = userRepo.findById(2).orElseThrow(Exception::new);
Post post = new Post(postDesc, user);
return postRepo.save(post);
}
public List<Post> getAllPostsByUser(int userId) {
User user = userRepo.findById(userId).get();
return postRepo.getAllPostsByUser(user);
}
}
data.sql
DROP TABLE IF EXISTS User;
CREATE TABLE User (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(250) NOT NULL
);
INSERT INTO User (name) VALUES
('Karan'),
('Ben'),
('John');
application.properties
server.port = 8081
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.main.allow-bean-definition-overriding=true
spring.jpa.hibernate.ddl-auto=update
spring.sql.init.data-locations=classpath:data.sql
spring.datasource.initialization-mode=always
Post.java
package com.interview.LLD.demo;
import javax.persistence.*;
@Entity
@Table(name = "Post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int postId;
private String postDesc;
@ManyToOne
@JoinColumn(name = "id",nullable = false)
private User user;
public Post() {
}
public Post(String postDesc, User user) {
this.postDesc = postDesc;
this.user = user;
}
public int getPostId() {
return postId;
}
public String getPostDesc() {
return postDesc;
}
public void setPostDesc(String postDesc) {
this.postDesc = postDesc;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
StackTrace:
java.lang.NullPointerException
at com.interview.LLD.demo.PostController.createPost(PostController.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Thanks in advance.
Got it! A silly mistake but I'm a noob to spring boot. In the @RequestBody
class, I'd named the int
param differently as to what I was sending in the request. My question then is, in spring do we have to have same names in request and in the class variables?
Why do you declare your path variable there and you don't use it ?
@GetMapping("/getAllByUser")
public List<Post> getAllPostsByUser(@PathVariable Integer user) {
return postService.getAllPostsByUser(user);
}
Instead you should pass the user id in the URL of the post request:
@GetMapping("/getAllByUser/{user})
public List<Post> getAllPostsByUser(@PathVariable("user") Integer user) {
return postService.getAllPostsByUser(user);
}
Of course it will trow a NullPointerException because you are calling the API with a null user.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.