为啥 spring boot 会返回一些值为 null 的 json?

Posted

技术标签:

【中文标题】为啥 spring boot 会返回一些值为 null 的 json?【英文标题】:why is spring boot returning me a json with null for some values?为什么 spring boot 会返回一些值为 null 的 json? 【发布时间】:2020-07-22 05:27:38 【问题描述】:

我正在制作一个练习游戏。

我有一个连接到 mysql 数据库的 spring boot/Maven 项目。我能够设置一个简单地从我的“allriddles”表中检索所有内容的 api。它以前工作过,但现在 api 返回一个 json,其中某些键的某些值为 null。我唯一玩的是spring boot文件上的application.properties。我在 spring.jpa.hibernate.ddl-auto 的“更新”和“无”之间跳跃。 我做错了什么?

application.properties

spring.jpa.hibernate.format_sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 
spring.datasource.url=jdbc:mysql://localhost:3306/riddlesgame
spring.datasource.username=root
spring.datasource.password=RiddlesGame886
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.data.rest.base-path=/api/v1
server.port=8088

这是数据库表和预期的列

这是返回的带有错误空值的 json

这是模型

@Entity
@Table(name = "allriddles")
public class Riddle 

/*
 * ATTRIBUTES
 */
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String title;
private int difficulty;
private String prize;
private String riddlerName;
private int levels;
private String riddleDescription;

/*
 * CONSTRUCTORS
 */
public Riddle() 
public Riddle( String title, int difficulty, String prize, String riddlerName, int levels,
        String description) 
    super();
    
    this.title = title;
    this.difficulty = difficulty;
    this.prize = prize;
    this.riddlerName = riddlerName;
    this.levels = levels;
    this.riddleDescription = description;


这是我调用服务的控制器

 @RestController
 public class GetRiddles 

@Autowired
RiddlesService rs; 


@RequestMapping("/Riddles")
public List<Riddle> getAllRiddles()
    return rs.getAllRiddles();

调用 crud 的服务

@Service
public class RiddlesService 

@Autowired
RiddlesRepository riddlesRepository;

public List<Riddle> getAllRiddles()
    List<Riddle> riddles = new ArrayList<>();
    riddlesRepository.findAll()
    .forEach(riddles::add);
    

    return riddles;

crud 界面

public interface RiddlesRepository extends CrudRepository<Riddle, Integer> 


如果有任何帮助,最后是控制台输出

【问题讨论】:

你能添加从stacktrace生成的sql吗 请分享您返回此 JSON 的 api 代码 @Kandy 我添加了控制台输出 @Sunil 我使用了 RestController、Service 和 CRUD jpa。我将它们添加到代码中。我的道歉 也添加控制器部分 【参考方案1】:

我尝试了同样的事情,得到了类似的结果。正如您所说,它发生在修改 spring.jpa.hibernate.ddl-auto 以进行更新时。它最终添加了 2 个新列。

Hibernate: alter table allriddles add column riddle_description varchar(255)
Hibernate: alter table allriddles add column riddler_name varchar(255)

原来的列名是 riddleDescription 和 riddlerName,而那些保留了现有的值。但是新列中不会有数据。因此,假设我重新创建了您遇到的相同问题,那么您必须

在数据库中:将数据从旧列(不带下划线)移动到新列(带下划线)并删除旧列。或者 在数据库中:删除新列(带下划线)。在 Riddle.java 中将属性 riddlerNameriddleDescription 更改为 riddlernameriddledescription

我假设您可能在某些时候也更改了这些属性名称的所有小写和驼峰式。因为 camelcase 属性会以下划线映射到数据库(例如 code - riddleName -> db column - riddle_name),而所有小写字母都不会有下划线(例如 code - riddlername -> db column - riddlerName 或 riddlername)。

【讨论】:

就是这样。我感激你。请问你是怎么知道这是问题所在?如果不是***,我什至不知道在哪里寻找这种类型的文档 @GioPoe 我用你的代码 sn-ps 运行并尝试了它,然后在日志中注意到它添加了 2 列,注意到它为驼峰添加了下划线。然后用谷歌搜索映射 JPA 属性并看到这篇有用的文章baeldung.com/hibernate-field-naming-spring-boot(你可以制定自己的策略)。我确实喜欢 Sunil 关于列名明确的回答,我倾向于有时更明确一些,而不是像这样使用隐式映射。【参考方案2】:

这是hibernate根据实体中定义的字段为表中的列命名的默认方式。

要覆盖您可以使用的默认行为

@Column(name = "riddleName")
private String riddlerName;

@Column(name = "riddleDescription")
private String riddleDescription;

【讨论】:

以上是关于为啥 spring boot 会返回一些值为 null 的 json?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 webflux 进行 spring boot 测试会忽略自定义 jackson 模块

为啥 Spring Boot Actuator 返回 404 而不是 401?

为啥 Spring Boot 返回一个字符串而不是 JSON

Spring Boot Actuator /env 端点以 XML 形式返回数据 - 为啥?

为啥 Jsp 文件不与 Spring Boot 中的控制器返回视图映射

为啥 Spring Boot 中的 REST 控制器返回 HTTP 状态 404 – 未找到