首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当项目同时使用JsonStringType和PostgreSQL时,从MySQL切换到PostgreSQL

当项目同时使用JsonStringType和PostgreSQL时,从MySQL切换到PostgreSQL
EN

Stack Overflow用户
提问于 2020-01-12 10:56:47
回答 2查看 6.7K关注 0票数 8

当有必要从PostgreSQL切换到MariaDB/MySql时,我遇到了json列的问题。

我使用Spring + JPA + Hibernate +hibernate-types 52。

我想要映射的桌子是这样的:

代码语言:javascript
复制
CREATE TABLE atable(
 ...
 acolumn JSON,
 ... 
);

好的,它适用于PostgreSQL和MariaDB/MySql。

问题是,当我希望部署一个应用程序时,它可以轻松地从一个应用程序切换到另一个应用程序,因为PostgreSQL和MySQL/MariaDB的正确hibernate类型-52实现是不同的。

这适用于MySQL/MariaDB。

代码语言:javascript
复制
@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonStringType.class)
  public class Atable {
  ...
  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;
  ...
}

这适用于PosgreSQL

代码语言:javascript
复制
@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonBinaryType.class)
public class Atable {
  ...
  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;
  ...
}

任何类型的解决方案,从JsonBinaryType切换到JsonStringType (或任何其他解决方案,以解决这一问题)将受到赞赏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-15 14:56:33

从Hibernate类型项目的2.11版本开始,您可以只使用JsonType,它可以与PostgreSQL、MySQL、Oracle、Server或H2一起使用。

所以,使用JsonType而不是JsonBinaryTypeJsonStringType

代码语言:javascript
复制
@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonType.class)
public class Atable {

  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;

}

就这样!

票数 11
EN

Stack Overflow用户

发布于 2020-05-20 17:06:26

您可以做一些疯狂的事情--限制是这只适用于特定类型和列:

首先,将静态@TypeDef替换为动态映射:

可以使用HibernatePropertiesCustomizer添加TypeContributorList

代码语言:javascript
复制
@Configuration
public class HibernateConfig implements HibernatePropertiesCustomizer {

  @Value("${spring.jpa.database-platform:}")
  private Class<? extends Driver> driverClass;

  @Override
  public void customize(Map<String, Object> hibernateProperties) {

    AbstractHibernateType<Object> jsonType;
    if (driverClass != null && PostgreSQL92Dialect.class.isAssignableFrom(driverClass)) {
      jsonType = new JsonBinaryType(Atable.class);
    } else {
      jsonType = new JsonStringType(Atable.class);
    }

    hibernateProperties.put(EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS,
        (TypeContributorList) () -> List.of(
            (TypeContributor) (TypeContributions typeContributions, ServiceRegistry serviceRegistry) ->
                typeContributions.contributeType(jsonType, "myType")));
  }
}

因此,这仅限于现在的Atable.class,我已经将这个定制的Json类型命名为“myType”。也就是说,您用@Type(type = 'myType')注释您的属性。

我在这里使用已配置的方言,但在我的应用程序中,我正在检查特定于DB的概要文件的活动配置文件。

还请注意,自Hibernate 5.3以来,TypeContributions .contributeType(BasicType, String...)就不再受欢迎了。我还没研究过新的机制。

这就涵盖了@Type部分,但是如果您想要使用Hibernate模式生成,您仍然需要@Column(columnDefinition = "...位,所以Hibernate知道要使用哪种列类型。

这是它开始感觉有点恶心的地方。我们可以注册Integrator来操作映射元数据:

代码语言:javascript
复制
hibernateProperties.put(EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER,
            (IntegratorProvider) () -> Collections.singletonList(JsonColumnMappingIntegrator.INSTANCE));

作为一个演示,我只检查PostgreSQL,并且只将动态columnDefinition应用于特定实体中的特定列:

代码语言:javascript
复制
public class JsonColumnMappingIntegrator implements Integrator {

  public static final JsonColumnMappingIntegrator INSTANCE =
      new JsonColumnMappingIntegrator();

  @Override
  public void integrate(
      Metadata metadata,
      SessionFactoryImplementor sessionFactory,
      SessionFactoryServiceRegistry serviceRegistry) {

    Database database = metadata.getDatabase();

    if (PostgreSQL92Dialect.class.isAssignableFrom(database.getDialect().getClass())) {
      Column acolumn=
        ((Column) metadata.getEntityBinding(Atable.class.getName()).getProperty("acolumn").getColumnIterator().next());
      settingsCol.setSqlType("json");
    }
  }

  @Override
  public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
  }
}

metadata.getEntityBindings()将为您提供所有实体绑定,您可以对其进行迭代,然后对属性进行迭代。不过,这似乎是相当低效的。我也不确定您是否可以设置'IS‘约束等,所以使用自定义创建脚本会更好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59703106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档