如何在H2中解决JSON列

我在应用程序MySQL 5.7中使用,我有JSON列。 当我尝试运行我的集成测试时不起作用,因为H2数据库无法创建表。 这是错误:

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: 

这是实体类。

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

而子类:

 public class Payload implements Serializable { private Long userId; private SubscriptionType type; private String paymentId; private List 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 getRatePlanId() { return ratePlanId; } public void setRatePlanId(List ratePlanId) { this.ratePlanId = ratePlanId; } public Integer getPeriod() { return period; } public void setPeriod(Integer period) { this.period = period; } } 

并且这个转换器用于插入数据库:

 public class JpaPayloadConverter implements AttributeConverter { // 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; } } 

H2没有JSON数据类型。

JSON本质上只是一个非常长的字符串,因此您可以使用大多数数据库中可用的CLOB。

只有在需要对其进行操作的SQL函数时,才需要行级的JSON类型,并且只有当数据库坚持其JSON函数在JSON类型而不是CLOB上运行时才需要。

我刚刚遇到了使用JSONB列类型的问题 – JSON类型的二进制版本,它不映射到TEXT

为了将来参考,您可以使用CREATE DOMAIN在H2中定义自定义类型,如下所示:

 CREATE domain IF NOT EXISTS jsonb AS other; 

这似乎对我有用,并允许我成功测试我的代码对实体。

资料来源: https : //objectpartners.com/2015/05/26/grails-postgresql-9-4-and-jsonb/

我在H2中使用TEXT类型解决了这个问题。 必须创建一个单独的数据库脚本,以便在H2中为测试创建模式,并用TEXT替换JSON类型。

这仍然是一个问题,因为如果你在查询中使用Json函数,你将无法在使用H2时测试它们。