获取org.hibernate.MappingException:否JDBC类型的方言映射:1111,使用com.vladmihalcea:hibernate-types-5

时间:2018-06-25 18:07:55

标签: java hibernate jpa spring-data-jpa hibernate-types

我正在尝试使用此库通过JPA和Hibernate持久化JSON:https://github.com/vladmihalcea/hibernate-types

我正在(每个有意义的细节中)关注本文中的示例:https://vladmihalcea.com/how-to-store-schema-less-eav-entity-attribute-value-data-using-json-and-hibernate/

这是我的(Gradle)依赖项:

compile 'com.vladmihalcea:hibernate-types-5:2.2.2'

这是我的实体类的来源:

package org.apereo.portal.fbms.data;

import com.fasterxml.jackson.databind.JsonNode;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "FBMS_FORM")
@TypeDef(
        name = "json",
        typeClass = JsonStringType.class
)
public class FormEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "FNAME", nullable = false, unique = true)
    private String fname; // TODO:  Regex-based validator

    @Column(name = "VERSION", nullable = false)
    private int version;

    @Column(name = "SCHEMA", nullable = false)
    @Type(type = "json")
    private JsonNode schema;

    @Column(name = "METADATA")
    @Type(type = "json")
    private JsonNode metadata;

    public Long getId() {
        return id;
    }

    // Additional getters and setters omitted for brevity...

}

我遇到此异常:

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688) ~[spring-beans-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626) ~[spring-beans-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        ... 16 common frames omitted
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111
        at org.hibernate.dialect.TypeNames.get(TypeNames.java:70) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.dialect.TypeNames.get(TypeNames.java:101) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:341) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.mapping.Column.getSqlType(Column.java:231) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.mapping.Table.sqlAlterStrings(Table.java:464) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.tool.schema.internal.SchemaMigratorImpl.migrateTable(SchemaMigratorImpl.java:254) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:170) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:60) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:134) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:101) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:472) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384) ~[spring-orm-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        ... 20 common frames omitted

如果有帮助...

  • 我尚未在RDBMS平台或JDBC驱动程序上提供任何信息;这是有意的-解决方案需要与数据库平台无关。
  • 我将对此实体使用spring-data-jpa。

3 个答案:

答案 0 :(得分:0)

在我的情况下,解决此问题的方法是添加自定义的休眠方言。 This资源可能会有所帮助。创建自定义方言类:

// CustomPostgreSQLDialect.java
public class CustomPostgreSQLDialect extends PostgreSQL10Dialect {

    public CustomPostgreSQLDialect() {
        super();
        registerHibernateType(Types.OTHER, StringArrayType.class.getName());
        registerHibernateType(Types.OTHER, IntArrayType.class.getName());
        registerHibernateType(Types.OTHER, JsonStringType.class.getName());
        registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
    }
}

,并且需要在属性中注册您的自定义方言

# application.yml
spring:
  jpa:
    properties:
      hibernate:
        dialect: "com.test.CustomPostgreSQLDialect"

,如果您需要通过CustomPostgreSQLDialect配置属性提供自定义hibernate.dialect

<property
    name="hibernate.dialect"
    value="com.test.CustomPostgreSQLDialect"
/>

答案 1 :(得分:0)

根据触发该异常的操作,您有不同的解决方法。

在您的情况下,您在引导过程中遇到了问题,这意味着Hibernate方言没有1111 JDBC列类型(代表Types.OTHER)的映射。因此,您需要使用当前的方言注册它,就像这样:

public class PostgreSQL95JsonDialect
        extends PostgreSQL95Dialect {

    public PostgreSQL95JsonDialect() {
        super();
        this.registerHibernateType(
            Types.OTHER, JsonNodeBinaryType.class.getName()
        );
    }
}

可以使用自定义的“休眠方言”:

<property
    name="hibernate.dialect"
    value="com.vladmihalcea.book.hpjp.hibernate.type.json.PostgreSQL95JsonDialect"
/>

如果在执行SQL本机查询时遇到此异常,则需要通过addScalar传递类型:

JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
    "SELECT properties " +
    "FROM book " +
    "WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("properties", JsonNodeBinaryType.INSTANCE)
.getSingleResult();

assertEquals(
    "High-Performance Java Persistence",
    properties.get("title").asText()
);

有关此主题的更多详细信息,请同时查看https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html

答案 2 :(得分:-1)

我认为Vlad的库中有一个错误-当我将列定义从json更改为text@Column(columnDefinition = "text"))时,一切正常。

但是我认为您应该use jsonb而不是json。使用“ jsonb”,所有功能均可按预期运行:

@Column(name = "METADATA", columnDefinition = "jsonb")
@Type(type = "jsonb")
private JsonNode metadata;

观看我的演示:sb-hibernate-types-demo

已更新

一种解决方法-使用自定义的Hibernate方言,我已经在代码clob(1111)中注册了列类型Types.OTHER,一切正常。在H2HSQLD数据库上进行了测试。