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

新手上路,请多包涵

我们有一个包含很多列的大表。我们迁移到 MySQL Cluster 后,无法创建表,原因是:

错误 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 字符串?

原文由 Rad 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

您可以使用 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。

原文由 Alessandro Polverini 发布,翻译遵循 CC BY-SA 4.0 许可协议

JPA AttributeConverter 对于映射 JSON 对象类型来说太有限了,尤其是当你想将它们保存为 JSON 二进制文件时。

您不必创建自定义 Hibernate Type 来获得 JSON 支持,您需要做的就是使用 Hibernate Types OSS 项目

例如,如果您使用的是 Hibernate 5.2 或更新版本,那么您需要在 Maven pom.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` 类型由 `MySQL57Dialect` 自动注册。

否则,您需要自己注册:

public class MySQLJsonDialect extends MySQL55Dialect {

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

}

”`

并且,设置 hibernate.dialect Hibernate 属性以使用您刚刚创建的 MySQLJsonDialect 类的完全限定类名。

原文由 Vlad Mihalcea 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题