1

I have json file with json object as value of property inside:

{
 "name": "name",
 "json": {...}
}

I need to get it automatically in RestController and use it as entity in JPA+Hibernate.

My entity is:

UPDATE -> more specified entity

@Entity
@Table(name = "collections")
public class Collection {
    @Id
    private String name;

    @Column(name = "cache_limit")
    private int limit;

    @Column(name = "cache_algorithm")
    private String algorithm;

    @Transient
    private JsonNode schema;

    @JsonIgnore
    @Column(name ="json_schema")
    private String jsonSchema;

    public Collection() {
    }

    public String getJsonSchema() {
        return schema.toString();
    }

    public void setJsonSchema(String jsonSchema) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            schema = mapper.readTree(jsonSchema);
        } catch (IOException e) {
            throw new RuntimeException("Parsing error -> String to JsonNode");
        }
    }

   ..setters and getters for name limit algorithm schema..
}

When I use entityManager.persist(Collection) I have json_schema column as NULL

How can I solve It? The problem is in setJsonSchema() perhaps

update:

public String getJsonSchema() {
        return jsonSchema;
    }

    public void setJsonSchema(JsonNode schema) {
        this.jsonSchema = schema.toString();
    }

Such getters/setters don't solve the problem

1
  • 1
    What do you mean by "json field would be empty."? Your controller looks like Cat getCat(int name){ return cats.getCatByName(name);} and it returns JSON object with name and json property is empty? Commented Mar 3, 2019 at 23:59

3 Answers 3

1

You could define JsonNode json property as @Transient so JPA does not try to store it on database. However, jackson should be able to translate it back and forward to Json.

Then you can code getter/setter for JPA, so you translate from JsonNode to String back and forward. You define a getter getJsonString that translate JsonNode json to String. That one can be mapped to a table column, like 'json_string', then you define a setter where you receive the String from JPA and parse it to JsonNode that will be avaialable for jackson.

Do not forget to add @JsonIgnore to getJsonString so Jackson does not try to translate to json as jsonString.

@Entity
@Table(name = "cats")
public class Cat {

  private Long id;

  private String name;

  @Transient
  private JsonNode json;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }

  @Column(name ="name")
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setId(Long id) {
    this.id = id;
  }

  // Getter and setter for name

  @Transient
  public JsonNode getJson() {
    return json;
  }

  public void setJson(JsonNode json) {
    this.json = json;
  }


  @Column(name ="jsonString")
  public String getJsonString() {
    return this.json.toString();
  }

  public void setJsonString(String jsonString) {
    // parse from String to JsonNode object
    ObjectMapper mapper = new ObjectMapper();
    try {
      this.json = mapper.readTree(jsonString);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
Sign up to request clarification or add additional context in comments.

11 Comments

It's a bit strange, but json.asText() doesn't work. json.toString() works
When i use JPA this @JsonIgnore column is NULL
Can you debug and see what is the value of json on get/setJsonString?
get/setJsonString work correctly. After using entityManager.persist(cat) i have NULL in database
I can remove @Column(name ="json_string") - the result would be the same
|
1

As explained in this article, you don't have to create a custom Hibernate Type manually since you can simply get it via Maven Central using the following dependency:

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

For more info, check out the Hibernate Types open-source project.

Then you can simply declare the new type you class.

@TypeDef(
    name = "jsonb-node", 
    typeClass = JsonNodeBinaryType.class
)

And the entity mapping will look like this:

@Type(type = "json-node")
@Column(columnDefinition = "json")
private JsonNode json;

Comments

0

Create response without putting logic into entity setter/getter, without third party dependencies:

ObjectNode node = JsonNodeFactory.instance.objectNode();
node.put("name", cat.getName());
node.set("json", new ObjectMapper().readTree(cat.getJson()));
return Response.ok(node).build();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.