Java преобразование объекта в postgres jsonb - PullRequest
1 голос
/ 18 марта 2020

Я пытаюсь сохранить объект java в столбце jsonb в базе данных Postgres, используя eclipselink, но в данный момент я застрял при написании соответствующего конвертера. Кто-нибудь может мне помочь или дать хороший пример сохранения типов jsonb в java с eclipselink?

Вот код модели:

@Entity
@Table(name = TABLE_NAME)
public class SystemEventModel implements Serializable {

   public static final String TABLE_NAME = "system_event";

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

   @Lob
   @Column(name = "event_data", columnDefinition = "jsonb")
   private JsonObject eventData;

   public SystemEventModel(JsonObject eventData) {
        this.eventData = eventData;
    }       
}

В настоящее время я просто получаю сообщение об ошибке "ОШИБКА : столбец "event_data" имеет тип jsonb, но выражение имеет тип bytea ", когда я пытаюсь сохранить этот объект. Я знаю, почему это так, но я не знаю, как написать конвертер, так как я не понимаю, в какой тип мне следует конвертировать тип JsonObject, чтобы он передавался как jsonb.

Вот что Я имею в виду в этом примере конвертера:

@Converter(autoApply = true)
public class AppAttributeTypeAttributeConverter implements AttributeConverter<JsonObject, ???> {

    @Override
    public ??? convertToDatabaseColumn(JsonObject eventData) {
        return ???;
    }

    @Override
    public JsonObject convertToEntityAttribute(??? eventData) {
        return ???;
    }
}

А вот фрагмент для сохранения:

    String details = "{ \"pressed\": \"yes\", \"isDefault\": \"true\", \"type\": \"BUTTON\"}";
    JsonReader jsonReader = Json.createReader(new StringReader(details));
    JsonObject jsonObject = jsonReader.readObject();
    jsonReader.close();
    SystemEventModel eventModel = new SystemEventModel(jsonObject);
    em.persist(eventModel);

Заранее спасибо!

1 Ответ

0 голосов
/ 18 марта 2020

Вот что вы можете сделать, чтобы это работало:

Изменить

 @Lob
 @Column(name = "event_data", columnDefinition = "jsonb")
 private JsonObject eventData;

на

 @Lob
 @Type(type = "jsonb")
 @Column(name = "event_data", columnDefinition = "jsonb")
 private String eventData;

 public SystemEventModel(String eventData) {
    this.eventData = eventData;
 }

Затем сохраните, используя это:

String details = "{ \"pressed\": \"yes\", \"isDefault\": \"true\", \"type\": \"BUTTON\"}";
SystemEventModel eventModal = new SystemEventModel(details); // or you can use setter method.
em.persist(eventModel);

Надеюсь, это поможет !!

См. Как сопоставить свойство String JPA с JSON колонка с использованием Hibernate

Спасибо ...

РЕДАКТИРОВАТЬ: -

  @Override
  public Object convertToDatabaseColumn(JsonObject eventData) {
    try {
      PGobject out = new PGobject();
      out.setType("json");
      out.setValue(eventData.toString());
      return out;
    } catch (Exception e) {
      throw new IllegalArgumentException("Unable to serialize to json field ", e);
    }
  }

  @Override
  public JsonObject convertToEntityAttribute(Object eventData) {
    try {
      if (eventData instanceof PGobject && ((PGobject) eventData).getType().equals("json")) {
        return mapper.reader(new TypeReference<JsonObject>() {
        }).readValue(((PGobject) eventData).getValue());
      }
      return Json.createObjectBuilder().build();
    } catch (IOException e) {
      throw new IllegalArgumentException("Unable to deserialize to json field ", e);
    }
  }

Это решение, которое я нашел для JPA не специально для спящего или затмения.

...