title: How to map a JSON column with H2, JPA, and Hibernate
body: <p>I use in application MySQL 5.7 and I have JSON columns. When I try running my integration tests don't work because the H2 database can't create the table. This is the error:</p>
  
  <pre><code>2016-09-21 16:35:29.729 ERROR 10981 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: create table payment_transaction (id bigint generated by default as identity, creation_date timestamp not null, payload json, period integer, public_id varchar(255) not null, state varchar(255) not null, subscription_id_zuora varchar(255), type varchar(255) not null, user_id bigint not null, primary key (id))
  2016-09-21 16:35:29.730 ERROR 10981 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : Unknown data type: "JSON"; SQL statement:
  </code></pre>
  
  <p>This is the entity class.</p>
  
  <pre><code>@Table(name = "payment_transaction")
  public class PaymentTransaction extends DomainObject implements Serializable {
  
      @Convert(converter = JpaPayloadConverter.class)
      @Column(name = "payload", insertable = true, updatable = true, nullable = true, columnDefinition = "json")
      private Payload payload;
  
      public Payload getPayload() {
          return payload;
      }
  
      public void setPayload(Payload payload) {
          this.payload = payload;
      }
  }
  </code></pre>
  
  <p>And the subclass:</p>
  
  <pre><code>public class Payload implements Serializable {
  
      private Long userId;
      private SubscriptionType type;
      private String paymentId;
      private List&lt;String&gt; ratePlanId;
      private Integer period;
  
      public Long getUserId() {
          return userId;
      }
  
      public void setUserId(Long userId) {
          this.userId = userId;
      }
  
      public SubscriptionType getType() {
          return type;
      }
  
      public void setType(SubscriptionType type) {
          this.type = type;
      }
  
      public String getPaymentId() {
          return paymentId;
      }
  
      public void setPaymentId(String paymentId) {
          this.paymentId = paymentId;
      }
  
      public List&lt;String&gt; getRatePlanId() {
          return ratePlanId;
      }
  
      public void setRatePlanId(List&lt;String&gt; ratePlanId) {
          this.ratePlanId = ratePlanId;
      }
  
      public Integer getPeriod() {
          return period;
      }
  
      public void setPeriod(Integer period) {
          this.period = period;
      }
  
  }
  </code></pre>
  
  <p>And this converter for insert in database:</p>
  
  <pre><code>public class JpaPayloadConverter implements AttributeConverter&lt;Payload, String&gt; {
  
      // ObjectMapper is thread safe
      private final static ObjectMapper objectMapper = new ObjectMapper();
  
      private Logger log = LoggerFactory.getLogger(getClass());
  
      @Override
      public String convertToDatabaseColumn(Payload attribute) {
          String jsonString = "";
          try {
              log.debug("Start convertToDatabaseColumn");
  
              // convert list of POJO to json
              jsonString = objectMapper.writeValueAsString(attribute);
              log.debug("convertToDatabaseColumn" + jsonString);
  
          } catch (JsonProcessingException ex) {
              log.error(ex.getMessage());
          }
          return jsonString;
      }
  
      @Override
      public Payload convertToEntityAttribute(String dbData) {
  
          Payload payload = new Payload();
          try {
              log.debug("Start convertToEntityAttribute");
  
              // convert json to list of POJO
              payload = objectMapper.readValue(dbData, Payload.class);
              log.debug("JsonDocumentsConverter.convertToDatabaseColumn" + payload);
  
          } catch (IOException ex) {
              log.error(ex.getMessage());
          }
          return payload;
  
      }
  }
  </code></pre>