Сохранить Raw JSON как строку в базе данных - PullRequest
0 голосов
/ 12 марта 2019

Как я могу сохранить Raw Json как String в базе данных MsSql с запросом POST - используя Jackson ObjectMapper для преобразования строки в Json, но не в состоянии преобразовать raw Json в строку?

{
     "id": 1,
     "someName":"someName",
     "json": {
         "title": "example glossary",
         "GlossDiv": {
             "title": "S",
             "GlossTerm": "Standard Generalized Markup Language"
         }
},
     "anotherjson":{
          "name":"someone",
          "age": 121
},
     "somedate":"03-11-2019.00:00:00" 
}

Как можноЯ сохраняю это сохранить JSON как целое число, varchar, строка, строка, столбец даты в БД?1, someName, "{" title ":" example Glossary "," GlossDiv ": {" title ":" S "," GlossTerm ":" Стандартный обобщенный язык разметки "}", "{" name ":" somebody ", "age": 121} ", 03-11-2019.00: 00: 00.

** Обновление ** Для простоты представлен простой json

{
"id":1,
"jsonObjectHolder":{
        "name": "Name",
        "age" : 404
        }}

Контроллер:

@PostMapping("/postJson")
public void postJson(@RequestBody TryJson tryJson) {
    tryJsonService.postJson(tryJson);
}

Сервис:

public void postJson(TryJson tryJson) {
    tryJsonRepository.save(tryJson);
}

Репо:

public interface TryJsonRepository extends CrudRepository<TryJson, Integer> {

}

Модель:

@Entity

@ Таблица (name = "TryJson") открытый класс TryJson {

@Id
@Column(name = "id")
private Integer id;

@JsonIgnore
@Column(name = "json_column")
private String jsonColumn;

@Transient
private JsonNode jsonObjectHolder;

public TryJson() {
}

public TryJson(Integer id, String jsonColumn) {
    this.id = id;
    this.jsonColumn = jsonColumn;
}

public Integer getId() {
    return id;
}

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

public JsonNode getJsonObjectHolder() {
    return jsonObjectHolder;
}

public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
    this.jsonObjectHolder = jsonObjectHolder;
}

public String getJsonColumn() {
    return this.jsonObjectHolder.toString();
}

public void setJsonColumn(String jsonColumn) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    this.jsonObjectHolder = mapper.readTree(jsonColumn);
}

@Override
public String toString() {
    return String.format("TryJson [Id=%s, JsonColumn=%s, jsonObjectHolder=%s]", id, jsonColumn, jsonObjectHolder);
}

}

http://localhost:8080/api/postJson

ID JSON_COLUMN
1 ноль

Не уверенчего мне здесь не хватаетЯ получаю заполнение jsonObjectHolder во время отладки, но все равно получаю NULL TryJson [Id = 1, JsonColumn = null, jsonObjectHolder = {"name": "Name", "age": 404}]

Обновление 2

Я получаю исключение нулевого указателя.

 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Exception occurred inside getter of com.example.tryjson.tryjson.model.TryJson.jsonColumn; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside getter of com.example.tryjson.tryjson.model.TryJson.jsonColumn] with root cause 
java.lang.NullPointerException: null
at com.example.tryjson.tryjson.model.TryJson.getJsonColumn(TryJson.java:52) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_192]

Вот моя новая модель

@Entity
@Table(name = "TryJson")
public class TryJson {
private Integer id;

@Transient
private JsonNode jsonObjectHolder;

public TryJson() {
}

public TryJson(Integer id, JsonNode jsonObjectHolder) {
    this.id = id;
    this.jsonObjectHolder = jsonObjectHolder;
}

@Id
@Column(name = "id")
public Integer getId() {
    return id;
}

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

@Transient
public JsonNode getJsonObjectHolder() {
    return jsonObjectHolder;
}

public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
    this.jsonObjectHolder = jsonObjectHolder;
}

@Column(name = "json_column")
public String getJsonColumn() {
    return this.jsonObjectHolder.toString();
}

public void setJsonColumn(String jsonColumn) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    this.jsonObjectHolder = mapper.readTree(jsonColumn);
}
}

1 Ответ

0 голосов
/ 12 марта 2019

Вы можете определить свойство JsonNode json для хранения части, которую вы хотите сохранить как текст, а затем пометить ее как @Transient, чтобы JPA не пытался сохранить ее в базе данных.Тем не менее, Джексон должен быть в состоянии перевести его назад и вперед в Json.

Затем вы можете кодировать getter / setter для JPA, так что вы переводите из JsonNode в String назад и вперед.Вы определяете геттер getJsonString, который переводит JsonNode json в String.Это можно сопоставить со столбцом таблицы, например «json_string», затем вы определяете установщик, в который вы получаете строку из JPA, и анализируете ее в JsonNode, который будет доступен для Джексона.

Не забудьте добавить@JsonIgnore для getJsonString, поэтому Джексон не пытается преобразовать в json как jsonString.

@Entity
@Table(name = "request")
public class Request {

  private Long id;

  private String someName;

  @Transient
  private JsonNode json;

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

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

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

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

  // Getter and setter for name

  @Transient  // This is for Jackson
  public JsonNode getJson() {
    return json;
  }

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


  @Column(name ="jsonString")
  public String getJsonString() { // This is for JPA
    return this.json.toString();
  }

  public void setJsonString(String jsonString) {  // This is for JPA
    // parse from String to JsonNode object
    ObjectMapper mapper = new ObjectMapper();
    try {
      this.json = mapper.readTree(jsonString);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

UPDATE:

Если вы пометите jsonColumn с пружиной @Column, будет использоваться отражениечтобы извлечь данные с инициализацией по умолчанию null, getJsonColumn перевод никогда не будет выполнен:

@JsonIgnore
@Column(name = "json_column")
private String jsonColumn;

Вам не нужен jsonColumn, просто убедитесь, что вы установили свои сеттеры @Column, поэтомуSpring использует gettets / setters для сохранения в базе данных, при сохранении jpa выполнит getJsonColumn, при чтении jpa выполнит setJsonColumn, а jsonNode будет преобразован назад и вперед в строку:

@Entity
@Table(name = "TryJson") public class TryJson {

  private Integer id;

  @Transient
  private JsonNode jsonObjectHolder;

  public TryJson() {
  }

  public TryJson(Integer id, String jsonColumn) {
      this.id = id;
      this.jsonObjectHolder = // use mapper to create the jsonObject;
  }

  @Id
  @Column(name = "id")
  public Integer getId() {
      return id;
  }

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

  public JsonNode getJsonObjectHolder() {
      return jsonObjectHolder;
  }

  public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
      this.jsonObjectHolder = jsonObjectHolder;
  }

  @Column(name = "json_column")
  public String getJsonColumn() {
      return this.jsonObjectHolder.toString();
  }

  public void setJsonColumn(String jsonColumn) throws IOException {
      ObjectMapper mapper = new ObjectMapper();
      this.jsonObjectHolder = mapper.readTree(jsonColumn);
  }

  @Override
  public String toString() {
      return String.format("TryJson [Id=%s, JsonColumn=%s, jsonObjectHolder=%s]", id, jsonColumn, jsonObjectHolder);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...