无法从 h2 获取数据

Posted

技术标签:

【中文标题】无法从 h2 获取数据【英文标题】:Unable to get data from h2 【发布时间】:2021-07-22 13:20:59 【问题描述】:

我正在尝试做一个简单的任务。我有一个 API 正在尝试使用 userId 和 post desc 作为参数创建一个帖子。我正在使用 data.sql 直接初始化 h2 DB 中的用户。在 PostService 中,我试图通过 userId 使用 userRepo.findById(userId) 获取用户。参数从请求传递给服务。但是,我没有得到任何用户。我收到了NullPointerException。我检查了 h2 db,我可以看到我的用户在场。即使是 sout 也无法正常工作。 尝试了一些来自互联网的答案,目前还没有运气。

代码如下:

用户.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);
    

数据.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)

提前致谢。

【问题讨论】:

可以添加stacktrace吗? 像这样在@GetMapping 中声明路径变量:@GetMapping("/getAllByUser/user") 在问题中添加了堆栈跟踪。 在调用 createPost 方法之前添加日志语句以查看您正在发送的请求正文。 不知何故我将 userId 设为空。这是我的请求 "desc": "Hello World", "userId": 1 【参考方案1】:

知道了! 一个愚蠢的错误,但我是弹簧靴的菜鸟。在@RequestBody 类中,我将int 参数命名为与我在请求中发送的内容不同。那么我的问题是,在春季,我们是否必须在请求和类变量中使用相同的名称?

【讨论】:

是的,那么只有 spring boot 才能将 json 映射到 pojo 类。 您可以使用Jackson注解@JsonProperty将JSON属性名称映射到注解的Java字段名称。 我知道只是想保持简单。【参考方案2】:

为什么你在那里声明你的路径变量而不使用它?

@GetMapping("/getAllByUser")
    public List<Post> getAllPostsByUser(@PathVariable Integer user) 
        return postService.getAllPostsByUser(user);
    

您应该在发布请求的 URL 中传递用户 ID:

@GetMapping("/getAllByUser/user)
    public List<Post> getAllPostsByUser(@PathVariable("user") Integer user) 
        return postService.getAllPostsByUser(user);
    

当然,它会抛出 NullPointerException,因为您使用 null 用户调用 API。

【讨论】:

我正在尝试创建一个帖子。所以我没有让 NPE 试图调用这个 API。我正在调用创建 API。

以上是关于无法从 h2 获取数据的主要内容,如果未能解决你的问题,请参考以下文章

H2 控制台无法访问 jbdc 数据库

如何使用 H2 嵌入式数据库获取序列中的下一个值?

H2 数据库,从表中获取数据的问题

Pl SQL 过程,用于将数据从一个表获取到另一个表

H2 嵌入式数据库在 Spring Boot 测试期间未获取属性

如何获取通过 H2DB 创建的“内存”数据库的流?