反序列化 JSON 会在表中创建另一个属性并且无法正确返回数据

Posted

技术标签:

【中文标题】反序列化 JSON 会在表中创建另一个属性并且无法正确返回数据【英文标题】:Deserializing JSON creates another attribute in the table and doesn't return data correctly 【发布时间】:2020-11-11 10:04:48 【问题描述】:

我目前正在尝试使用 SpringBoot 连接到我的 mysql 数据库“CoffeeShop”并返回“menu”表中的所有记录。但问题是它返回记录数,但只返回第一条记录,重复 4 次(表中有 4 条记录)并向表中添加另一个“primary_id”键

这就是我的“菜单”表在 MySQL 中的显示方式:

+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| product id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(100)     | NO   |     | NULL    |                |
| price      | double           | NO   |     | NULL    |                |
| size       | varchar(126)     | YES  |     | NULL    |                |
| type       | varchar(126)     | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+

这是调用页面后表格的显示方式:

+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| product id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(100)     | NO   |     | NULL    |                |
| price      | double           | NO   |     | NULL    |                |
| size       | varchar(126)     | YES  |     | NULL    |                |
| type       | varchar(126)     | YES  |     | NULL    |                |
| product_id | int(11)          | NO   |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+

注意新属性“product_id”,这是为什么返回的 JSON 格式是我在开头提到的格式的副产品。

这是我用来表示每条记录的 Menu 类:

@Entity
public class Menu 

    @Id
    private Integer productId;

    private String name;

    private Double price;

    private String size;

    private String type;

    public Integer getProductId() 
        return this.productId;
    

    @JsonSetter("product id")
    public void setProductId(Integer productId) 
        this.productId = productId;
    

    //And the rest of the setters/getters omitted...

这是我正在使用的“CrudRepository”

public interface MenuRepository extends CrudRepository<Menu, Integer> 
    

这是我的“application.properties”文件的内容

spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverclassname = com.mysql.jdbc.Driver
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://$MYSQL_HOST:localhost:3306/CoffeeShop
spring.datasource.username=springuser
spring.datasource.password=ThePassword

这是我用于请求的控制器:

@RestController
public class MenuController 
    
    @Autowired
    private MenuRepository menuRepository;

    @GetMapping(path="/menu")
    public Iterable<Menu> getFullMenu()
        return  menuRepository.findAll();
    

【问题讨论】:

【参考方案1】:

我会说问题是因为字段具有不同的名称(空格),所以在创建表时 JPA 认为它们是不同的字段。

我的建议是不要将Menu 类用作实体和响应,而是将其拆分为两个不同的类。 它将避免您暴露的数据与您的内部数据混合。在这种特定情况下,您不需要实体类中的 @JsonSetter 注释,它将位于 DTO 类中。

见:https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

这也可能对您有所帮助:Spring Boot @ManyToOne only Id @JsonProperty

【讨论】:

以上是关于反序列化 JSON 会在表中创建另一个属性并且无法正确返回数据的主要内容,如果未能解决你的问题,请参考以下文章

将Json反序列化为Entity Framework无法将int转换为type

ajxa的html和json格式

无法反序列化当前的JSON对象,为啥

反序列化以 @ 开头的 JSON 属性

在使用 Jackson 反序列化期间选择性地忽略 JSON 属性

使用 Json.NET 转换器反序列化属性