1

I'm trying to persist java object into jsonb column into Postgres database using eclipselink, but I am stuck at the moment on writing an appropriate converter. Can anyone help me or give me a good example of persisting jsonb types in java with eclipselink?

Here is model code:

@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;
    }       
}

Currently, I just get the error "ERROR: column "event_data" is of type jsonb but the expression is of type bytea" when I try to persist this object. I'm aware why it is but I don't know how to write a converter since I don't understand in what type should I convert the JsonObject type for it to get passed like jsonb.

Here is what I mean in this converter sample:

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

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

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

And here is snippet for persisting:

    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);

Thanks in advance!

1

1 Answer 1

-2

Here is what you can do that may work:

Change

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

to

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

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

Then persist by using this:

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

I hope it helps!!

Refer How to map a String JPA property to a JSON column using Hibernate

Thanks...

EDIT:-

  @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);
    }
  }

This is the Solution I found for JPA not specifically for hibernate or eclipselink.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! But, this would probably work with Hibernate implementation and is not for EclipseLink.
It does not work with EclipseLink and it does not work with Hibernate 6+

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.