当前位置: 首页 > 知识库问答 >
问题:

如何使用JPA映射JSON列到Java对象

曾飞雨
2023-03-14

我们有一张有很多柱子的大桌子。在我们移动到MySQL集群后,表无法创建,因为:

错误1118 (42000):行大小过大。使用的表类型(不包括BLOB)的最大行大小为14000。这包括存储开销,检查手册。您必须将一些列更改为TEXT或BLOB

例如:

@Entity @Table (name = "appconfigs", schema = "myproject")
public class AppConfig implements Serializable
{
    @Id @Column (name = "id", nullable = false)
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private int id;

    @OneToOne @JoinColumn (name = "app_id")
    private App app;

    @Column(name = "param_a")
    private ParamA parama;

    @Column(name = "param_b")
    private ParamB paramb;
}

它是一个用于存储配置参数的表。我在想,我们可以将一些列组合成一个列,并将其存储为JSON对象,并将其转换为Java对象。

例如:

@Entity @Table (name = "appconfigs", schema = "myproject")
public class AppConfig implements Serializable
{
    @Id @Column (name = "id", nullable = false)
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private int id;

    @OneToOne @JoinColumn (name = "app_id")
    private App app;

    @Column(name = "params")
    //How to specify that this should be mapped to JSON object?
    private Params params;
}

我们定义了:

public class Params implements Serializable
{
    private ParamA parama;
    private ParamB paramb;
}

通过使用它,我们可以将所有列合并为一个列并创建表。或者我们可以把整张桌子分成几张桌子。就我个人而言,我更喜欢第一种解决方案。

无论如何,我的问题是如何映射Params列,它是文本,包含Java对象的JSON字符串?

共有3个答案

鲜于河
2023-03-14

如果在响应客户端时需要将json类型属性映射为json格式(例如rest API响应),请添加@JsonRawValue,如下所示:

@Column(name = "params", columnDefinition = "json")
@JsonRawValue
private String params;

这可能不会为服务器端使用进行DTO映射,但客户端会将属性正确格式化为json。

越新霁
2023-03-14

JPAAttributeConverter对于映射JSON对象类型来说太有限了,特别是如果您想将它们保存为JSON二进制文件的话。

您不必创建自定义Hibernate类型来获得JSON支持,只需使用Hibernate类型OSS项目即可。

例如,如果您使用的是Hibernate 5.2或更新版本,那么您需要在Mavenpom.xml配置文件中添加以下依赖项:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types.version}</version> 
</dependency> 

现在,您需要使用@MappedSuperclass在实体属性级别或者更好的是在基类的类级别声明新类型:

@TypeDef(name = "json", typeClass = JsonType.class)

实体映射将如下所示:

@Type(type = "json")
@Column(columnDefinition = "json")
private Location location;

如果您使用的是Hibernate 5.2或更高版本,那么JSON类型将由mysql57dial自动注册。

否则,您需要自己注册:

public class MySQLJsonDialect extends MySQL55Dialect {

    public MySQLJsonDialect() {
        super();
        this.registerColumnType(Types.JAVA_OBJECT, "json");
    }
}

然后,设置hibernate。方言Hibernate属性使用刚刚创建的MySQLJsonDialect类的完全限定类名。

梁丘德寿
2023-03-14

可以使用JPA转换器将实体映射到数据库。只需向params字段添加类似于此的注释:

@Convert(converter = JpaConverterJson.class)

然后以类似的方式创建类(这将转换泛型对象,您可能希望对其进行专门化):

@Converter(autoApply = true)
public class JpaConverterJson implements AttributeConverter<Object, String> {

  private final static ObjectMapper objectMapper = new ObjectMapper();

  @Override
  public String convertToDatabaseColumn(Object meta) {
    try {
      return objectMapper.writeValueAsString(meta);
    } catch (JsonProcessingException ex) {
      return null;
      // or throw an error
    }
  }

  @Override
  public Object convertToEntityAttribute(String dbData) {
    try {
      return objectMapper.readValue(dbData, Object.class);
    } catch (IOException ex) {
      // logger.error("Unexpected IOEx decoding json from database: " + dbData);
      return null;
    }
  }

}

就是这样:您可以使用这个类将表中的任何对象序列化为json。

 类似资料:
  • 问题内容: 我们有一张有很多列的大桌子。移至MySQL Cluster后,由于以下原因无法创建表: 错误1118(42000):行大小太大。不包括BLOB在内的已使用表类型的最大行大小为14000。这包括存储开销,请查阅手册。您必须将某些列更改为TEXT或BLOB 举个例子: 这是用于存储配置参数的表。我在想,我们可以将一些列合并为一个列,并将其存储为JSON对象,然后将其转换为Java对象。 例

  • 问题内容: 我将MySQL列声明为 JSON 类型,并且在使用Jpa / Hibernate映射时遇到问题。我在后端使用Spring Boot。 这是我的代码的一小部分: 该程序返回一个错误,并告诉我无法映射该列。 在mysql表中,该列定义为: json_value JSON NOT NULL; 问题答案: 我更喜欢这样: 创建从Map到String的转换器(属性转换器),反之亦然。 使用Map

  • 问题内容: 我在了解如何实现这一目标方面遇到了问题。 基本上我们有一个API,用户发送以下格式的JSON :(如果代码不完美,请原谅,但您可以理解) 好的,我不确定我是否正确设置了JSON格式,但是现在这是我的问题。 我有一个带有参数Name,Last的类,还有一个作为其成员之一的对象Client和Property Date。 像这样: 因此,基本上,我不确定如何获取JSON,然后将其映射到我的对

  • 我编写了货币转换器程序,从,映射对象并创建选定速率的简单数据集。我的程序运行得很好,直到我停止使用解析和映射对象,并用替换它。它可以很好地读取基础货币和日期,但不能读取<代码>汇率 子对象。为什么? 我的代码:类别: 类: 必须使用映射对象的类: 我试图解析和映射的示例JSON数据 我正在使用这个对象来准备对象,该对象具有一个简单的

  • 问题内容: 我有一个具有以下结构的JPA实体对象: itemJsonString字段包含json字符串值,例如 并且itemJson字段包含对应的对象,该对象映射到json字符串。 我从数据库中获取此实体对象,如下所示: 现在,itemJson字段为空,因为它是一个瞬态字段。我必须使用Jackson的ObjectMapper手动设置它,如下所示: 我怎样才能做到这一点,当我这样做时,它会返回一个I