无法从 h2 获取数据
Unable to get data from h2
我正在尝试完成一项简单的任务。我有一个 API 试图创建一个 post 使用 userId 和 post desc 作为参数。我直接使用 data.sql 在 h2 DB 中初始化用户。在 PostService 中,我尝试使用 userRepo.findById(userId)
通过 userId 获取用户。参数从请求传递到服务。但是,我没有得到任何用户。我收到 NullPointerException
。我检查了 h2 数据库,我可以看到我的用户在场。即使是 sout 也无法正常工作。
从互联网上尝试了一些答案,到目前为止还没有成功。
代码如下:
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;
}
}
堆栈跟踪:
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)
提前致谢。
为什么你在那里声明你的路径变量而不使用它?
@GetMapping("/getAllByUser")
public List<Post> getAllPostsByUser(@PathVariable Integer user) {
return postService.getAllPostsByUser(user);
}
相反,您应该在 post 请求的 URL 中传递用户 ID:
@GetMapping("/getAllByUser/{user})
public List<Post> getAllPostsByUser(@PathVariable("user") Integer user) {
return postService.getAllPostsByUser(user);
}
当然它会抛出 NullPointerException,因为您正在用一个空用户调用 API。
知道了!
一个愚蠢的错误,但我是 spring 引导的菜鸟。在 @RequestBody
class 中,我对 int
参数的命名与我在请求中发送的内容不同。那么我的问题是,在 spring 中,我们是否必须在请求和 class 变量中使用相同的名称?
我正在尝试完成一项简单的任务。我有一个 API 试图创建一个 post 使用 userId 和 post desc 作为参数。我直接使用 data.sql 在 h2 DB 中初始化用户。在 PostService 中,我尝试使用 userRepo.findById(userId)
通过 userId 获取用户。参数从请求传递到服务。但是,我没有得到任何用户。我收到 NullPointerException
。我检查了 h2 数据库,我可以看到我的用户在场。即使是 sout 也无法正常工作。
从互联网上尝试了一些答案,到目前为止还没有成功。
代码如下:
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;
}
}
堆栈跟踪:
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)
提前致谢。
为什么你在那里声明你的路径变量而不使用它?
@GetMapping("/getAllByUser")
public List<Post> getAllPostsByUser(@PathVariable Integer user) {
return postService.getAllPostsByUser(user);
}
相反,您应该在 post 请求的 URL 中传递用户 ID:
@GetMapping("/getAllByUser/{user})
public List<Post> getAllPostsByUser(@PathVariable("user") Integer user) {
return postService.getAllPostsByUser(user);
}
当然它会抛出 NullPointerException,因为您正在用一个空用户调用 API。
知道了!
一个愚蠢的错误,但我是 spring 引导的菜鸟。在 @RequestBody
class 中,我对 int
参数的命名与我在请求中发送的内容不同。那么我的问题是,在 spring 中,我们是否必须在请求和 class 变量中使用相同的名称?