【问题标题】:Map a JsonNode object to a String field in SQL DB JPA将 JsonNode 对象映射到 SQL DB JPA 中的字符串字段
【发布时间】:2020-12-07 21:36:33
【问题描述】:

我有一个包含这些字段的 Sql 表:

id  uniqueidentifier primary key,
<--Omitting extra fields -->
metadata  nvarchar(max)

我也有一个实体映射到它:

@Data
public class GenericEntity implements Serializable {

  @Id
  @GeneratedValue(generator = "uuid2")
  @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
  @Type(type = "uuid-char")
  private UUID id;
<--Omitting extra properties -->
  @Type(type = "string")
  private JsonNode metadata;
}

第二个字段是 JsonNode 需要能够接受不同类型的 json 并将其作为字符串存储在表中。

如何转换 JsonNode 字段并将其作为字符串存储在数据库中,然后当我从表中读取时,它会将字符串转换回 JsonNode?​​p>

有效载荷:

{
    "id": "db8e8d4b-eee2-4507-bf30-f55c3f948724",
    <-- Omitting extra properties -->
    "metadata": {
        "description": "Sample",
        "location": "Stack Overflow"
    }
}

现在每次我尝试保存它时都会收到错误:

Could not determine type for: com.fasterxml.jackson.databind.JsonNode, at table: table_name, for columns: [org.hibernate.mapping.Column(metadata)]

【问题讨论】:

    标签: java jpa jsonnode


    【解决方案1】:

    我按照以下说明进行操作: https://www.baeldung.com/hibernate-custom-types

    创建了一个SqlTypeDescriptor

    public class JsonNodeStringType extends AbstractSingleColumnStandardBasicType<JsonNode> implements DiscriminatorType<JsonNode> {
    
      public static final JsonNodeStringType INSTANCE = new JsonNodeStringType();
    
      public JsonNodeStringType() {
        super(VarcharTypeDescriptor.INSTANCE, JsonNodeStringJavaDescriptor.INSTANCE);
      }
    
      @Override
      public String getName() {
        return "jsonnode";
      }
    
      @Override
      public JsonNode stringToObject(String xml) {
        return fromString(xml);
      }
    
      @Override
      public String objectToSQLString(JsonNode value, Dialect dialect) {
        return '\'' + toString(value) + '\'';
      }
    }
    

    然后我创建了一个 Java 类型描述符:

    public class JsonNodeStringJavaDescriptor extends AbstractTypeDescriptor<JsonNode> {
    
      public static final ObjectMapper mapper = new ObjectMapper();
    
      public static final JsonNodeStringJavaDescriptor INSTANCE = new JsonNodeStringJavaDescriptor();
    
      public JsonNodeStringJavaDescriptor() {
        super(JsonNode.class, ImmutableMutabilityPlan.INSTANCE);
      }
    
      @Override
      public String toString(JsonNode value) {
        try {
          return mapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
          throw new IllegalArgumentException("The given JsonNode object value: " + value + " cannot be transformed to a String", e);
        }
      }
    
      @Override
      public JsonNode fromString(String string) {
        try {
          return mapper.readTree(string);
        } catch (JsonProcessingException e) {
          throw new IllegalArgumentException("The given string value: " + string + " cannot be transformed to JsonNode object", e);
        }
      }
    
      @Override
      public <X> X unwrap(JsonNode value, Class<X> type, WrapperOptions options) {
        if (value == null) {
          return null;
        }
        if (String.class.isAssignableFrom(type)) {
          return (X) toString(value);
        }
        throw unknownUnwrap(type);
      }
    
      @Override
      public <X> JsonNode wrap(X value, WrapperOptions options) {
        if (value == null) {
          return null;
        }
        if (String.class.isInstance(value)) {
          return fromString(value.toString());
        }
    
        throw unknownWrap(value.getClass());
      }
    
    

    然后将类型定义添加到实体模型中

    @Data
    @TypeDef(name = "jsonnode", typeClass = JsonNodeStringType.class)
    public class GenericEntity implements Serializable {
    
      @Id
      @GeneratedValue(generator = "uuid2")
      @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
      @Type(type = "uuid-char")
      private UUID id;
    <--Omitting extra properties -->
      @Type(type = "jsonnode")
      private JsonNode metadata;
    }
    

    如果您不想手动创建这些类型描述符,也可以按照本文使用外部依赖项:https://vladmihalcea.com/sql-server-json-hibernate/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 2021-02-24
      • 2016-06-07
      • 2018-05-29
      • 2019-01-25
      相关资源
      最近更新 更多