Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA&x2B;JSON反序列化_Json_Spring_Jpa - Fatal编程技术网

JPA&x2B;JSON反序列化

JPA&x2B;JSON反序列化,json,spring,jpa,Json,Spring,Jpa,我对JPA非常陌生,使用Java作为REST服务的后端,我想将JSON存储到数据库中,并想检查一下最好的方法是什么。请让我知道,以防我走“漫长的道路” (我正在使用Spring) 我的数据: { frequency: "Week" isGoalOrMore: "true" name: "Develop" targetValue: "5" type: "Average" } java @Entity @Table(name = "habits") public class H

我对JPA非常陌生,使用Java作为REST服务的后端,我想将JSON存储到数据库中,并想检查一下最好的方法是什么。请让我知道,以防我走“漫长的道路”

(我正在使用Spring)

我的数据:

{
  frequency: "Week"
  isGoalOrMore: "true"
  name: "Develop"
  targetValue: "5"
  type: "Average"
}
java

@Entity
@Table(name = "habits")
public class Habit {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_habit_type")
    private HabitType type;

    private boolean isGoalOrMore; //basically means, achieve goal or do more
    private double targetValue;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_frequency")
    private Frequency frequency;

    //getters and setters
}
HabitType.java

 @Entity
 @Table(name = "habits_type")
 public class HabitType {

     @Id
     private Long id;

     private String description;

 }
数据库模型(mysql)

问题 当我试图保存此数据时,收到如下错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.tiperapp.model.HabitType] from String value ('Average'); no single-String constructor/factory method
我怎样才能解决它? 通过阅读一些主题,可以选择编写JSON反序列化程序。其他情况下,他们通过修正JPA解决了这个问题。 我想知道你推荐哪一种。。你们能帮我把这个反序列化吗,最好的方法?

你们的json是错误的

类型未映射到字符串,而是映射到对象。您可以使用以下方法来完成此操作:

{
  frequency: "Week"
  isGoalOrMore: "true"
  name: "Develop"
  targetValue: "5"
  type: {
    description: "A DESCRIPTION"
    id: "Average"
  }
}
你的json是错误的

类型未映射到字符串,而是映射到对象。您可以使用以下方法来完成此操作:

{
  frequency: "Week"
  isGoalOrMore: "true"
  name: "Develop"
  targetValue: "5"
  type: {
    description: "A DESCRIPTION"
    id: "Average"
  }
}

最好的解决方案,IMHO,是将向浏览器发送和接收的数据(我称之为DTO)和存储在数据库中的数据视为两种截然不同的东西

当然,它们看起来总是一样的。但它们是不同的。两种型号不能完全相同。例如:

  • 这些实体构成一个巨大的图形,通常包含双向关联,并且没有限制,因为所有内容都可以延迟加载。例如,订单行有订单,有买家,有地址,有城市,有国家,有。。。当浏览器请求订单行时,您不能合理地序列化所有这些图形,否则您将把数据库的一半序列化为JSON
  • JSON有时对同一事物的表示方式与数据库不同。例如,您将数据库中的所有习惯类型存储为一行,其中包含ID和描述,但JSON似乎只关心描述。ID似乎是一种避免在任何地方重复相同描述的方法
  • 最终用户看不到实体的许多属性(出于安全原因),或者仅与某些用例相关,等等
因此,我将使用不同的类来处理这两个问题。当您收到一个HabitTo作为JSON时,您可以使用Jackson将其反序列化为HabitTo实例,然后找到与DTO中的描述相对应的HabitType实体,并根据HabitTo中的相应信息创建/更新HabitType实体实例


概括地说:这些实体包含应用程序的完整业务模型,用于实现所有功能用例。DTO包含序列化信息,用于将一小部分信息传输到客户机或从客户机传输信息,通常用于特定的用例。将两者明确区分开来可以带来更大的灵活性:您可以在不更改服务接口的情况下更改基础持久性模型,反之亦然。

最好的解决方案,IMHO,是考虑您向/从浏览器(我称之为DTO)发送和接收的数据,以及存储在数据库中的数据,作为两种不同的东西

当然,它们看起来总是一样的。但它们是不同的。两种型号不能完全相同。例如:

  • 这些实体构成一个巨大的图形,通常包含双向关联,并且没有限制,因为所有内容都可以延迟加载。例如,订单行有订单,有买家,有地址,有城市,有国家,有。。。当浏览器请求订单行时,您不能合理地序列化所有这些图形,否则您将把数据库的一半序列化为JSON
  • JSON有时对同一事物的表示方式与数据库不同。例如,您将数据库中的所有习惯类型存储为一行,其中包含ID和描述,但JSON似乎只关心描述。ID似乎是一种避免在任何地方重复相同描述的方法
  • 最终用户看不到实体的许多属性(出于安全原因),或者仅与某些用例相关,等等
因此,我将使用不同的类来处理这两个问题。当您收到一个HabitTo作为JSON时,您可以使用Jackson将其反序列化为HabitTo实例,然后找到与DTO中的描述相对应的HabitType实体,并根据HabitTo中的相应信息创建/更新HabitType实体实例


概括地说:这些实体包含应用程序的完整业务模型,用于实现所有功能用例。DTO包含序列化信息,用于将一小部分信息传输到客户机或从客户机传输信息,通常用于特定的用例。将两者明确区分开来可以带来更大的灵活性:您可以在不更改服务接口的情况下更改基础持久性模型,反之亦然。

Hi Tahar,我只想发送一个字符串
Average
,它将与我的表相匹配。。此表基本上是一个域表,因此在我发送其他不可接受的值(如
Averge
)时,它可以避免错误。我想hibernate去我的数据库检查‘哦,你发送了平均值,它的id是2’,这可能吗?lol:)可以这样做,请参阅@JB Nizet关于dto用法的回答。嗨,塔哈尔,我只想发送一个字符串
Average
,它将与我的表匹配。。此表基本上是一个域表,因此在我发送其他不可接受的值(如
Averge
)时,它可以避免错误。我想hibernate去我的数据库检查‘哦,你发送了平均值,它的id是2’,这可能吗?lol:)这是可以做到的,请看@JB-nite关于dto用法的回答。哦,天哪!非常感谢你把这些放在一起!这很有道理,我没有想到你说的这些事情,比如有时你可能只想发送一封信