【问题标题】:No Dialect mapping for JDBC type: 1111没有 JDBC 类型的方言映射:1111
【发布时间】:2015-03-27 08:53:18
【问题描述】:

我正在开发一个 Spring JPA 应用程序,使用 MySQL 作为数据库。我确保所有 spring-jpa 库、hibernate 和 mysql-connector-java 都已加载。

我正在运行一个 mysql 5 实例。这是我的 application.properties 文件的摘录:

spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect

spring.datasource.url=jdbc:mysql://localhost/mydatabase
spring.datasource.username=myuser
spring.datasource.password=SUPERSECRET
spring.datasource.driverClassName=com.mysql.jdbc.Driver

执行集成测试时,spring 启动正常,但创建 hibernate SessionFactory 失败,例外情况:

org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

我认为我的方言应该是 Mysql5Dialect,我还尝试了一个明确说明 InnoDB 的方言,以及两个未指示版本 5 的方言选项。但我总是得到相同的“没有 JDBC 类型的方言映射: 1111'消息。 我的 application.properties 文件位于 test/resources 源文件夹中。它被 JUnit 测试运行程序识别(我之前因为输入错误而遇到异常)。

我设置的属性是否错误?我找不到关于这些属性名称的一些官方文档,但在这个 stackoverflow 答案中找到了提示:https://stackoverflow.com/a/25941616/1735497

期待您的回答,谢谢!

顺便说一句,应用程序已经在使用 spring boot。

【问题讨论】:

  • 错误信息表示一列返回的数据类型无法映射。 No Dialect mapping for JDBC type: 1111 表示 java.sql.Types.OTHER`。您从表格中选择了哪些列类型?
  • 哦,谢谢。我认为这意味着方言类型......是的,我喜欢使用 UUID 作为 ID,我们以前总是使用具有 UUID 列类型的 postgres。所以我们可以说@Type(type="pg-uuid");我不认为 mysql 有 UUID 列类型虽然
  • 刚发现和postgres很像:对id属性应用@Type(type="uuid-char")注解。
  • 如果在 SELECT 语句中放置一个 json 字段,我会遇到这个问题。我使用 PostgresSQL 和自定义休眠字段类型作为 json 类型。

标签: java mysql spring hibernate jpa


【解决方案1】:

如果使用 Postgres

public class CustomPostgreSqlDialect extends PostgreSQL94Dialect{

    @Override
    public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor)
    {
        switch (sqlTypeDescriptor.getSqlType())
        {
        case Types.CLOB:
            return VarcharTypeDescriptor.INSTANCE;
        case Types.BLOB:
            return VarcharTypeDescriptor.INSTANCE;
        case 1111://1111 should be json of pgsql
            return VarcharTypeDescriptor.INSTANCE;
        }
        return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
    }
    public CustomPostgreSqlDialect() {
        super();
        registerHibernateType(1111, "string");
    }}

并使用

<prop key="hibernate.dialect">com.abc.CustomPostgreSqlDialect</prop>

【讨论】:

    【解决方案2】:

    就我而言,问题在于 Hibernate 不知道如何处理 UUID 列。如果您使用的是 Postgres,请尝试将其添加到您的 resources/application.properties

    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
    

    【讨论】:

      【解决方案3】:

      另一个简单的解释可能是您正在获取复杂类型(实体/POJO)但未指定要映射到的实体:

      String sql = "select yourentity.* from {h-schema}Yourentity yourentity";
      return entityManager.createNativeQuery(sql).getResultList();
      

      只需在 createNativeQuery 方法中添加要映射到的类:

      return entityManager.createNativeQuery(sql, Yourentity.class).getResultList();
      

      【讨论】:

        【解决方案4】:

        查找触发问题的列

        首先,您没有提供实体映射,以便我们可以判断是哪一列产生了这个问题。例如,它可以是 UUIDJSON 列。

        现在,您正在使用一种非常古老的 Hibernate 方言。 MySQL5Dialect 适用于 MySQL 5。很可能您使用的是较新的 MySQL 版本。

        所以,请尝试改用MySQL8Dialect

        spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
        

        添加非标准类型

        如果您因为使用 JSON 列类型而遇到问题,请尝试提供支持非标准类型的自定义 Hibernate 方言:

        public class MySQL8JsonDialect
                extends MySQL8Dialect{
         
            public MySQL8JsonDialect() {
                super();
                this.registerHibernateType(
                    Types.OTHER, JsonStringType.class.getName()
                );
            }
        }
        

        Ans 使用自定义的 Hibernate 方言:

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

        如果在执行 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", JsonStringType.INSTANCE)
        .getSingleResult();
         
        assertEquals(
            "High-Performance Java Persistence",
            properties.get("title").asText()
        );
        

        【讨论】:

        • 添加方言没有帮助,不幸的是,在我的情况下,只有单元测试构建失败。 (UT 有本地数据库)@Vlad Mihalcea
        • 只要你在 Docker 容器中运行 MySQL 的集成测试,一切都会像魅力一样工作。如果您使用内存中的 DB,例如 H2 或 HSQLDB,它将无法正常工作。
        • 你在这里使用内存数据库,克服了那个错误,现在面临另一个错误。 Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement 也会尝试解决这个问题。
        【解决方案5】:

        函数或过程返回 void 会导致 JPA/Hibernate 出现一些问题,因此使用 return integer 更改它并在过程结束时调用 return 1 可能会解决问题。

        SQL 类型 1111 表示字符串。

        【讨论】:

          【解决方案6】:

          我遇到了同样的错误,这里的问题是存储在 DB 中的 UUID 没有转换为对象。

          我尝试应用这些注释 @Type(type="uuid-char")(对于 postgres @Type(type="pg-uuid")但它对我不起作用。

          这对我有用。假设您需要 JPA 中具有本机查询的表中的 id 和 name。使用字段 id 和 name 创建一个像“User”这样的实体类,然后尝试将 object[] 转换为我们想要的实体。这里匹配的数据是我们从查询中获得的对象数组的列表。

          @Query( value = "SELECT CAST(id as varchar) id, name from users ", nativeQuery = true)
          
          public List<Object[]> search();
          
          public class User{
             private UUID id;
             private String name;
          }
          
          
          List<User> userList=new ArrayList<>();
          
          for(Object[] data:matchedData){
                  userList.add(new User(UUID.fromString(String.valueOf(data[0])),
                          String.valueOf(data[1])));
          
              }
          

          假设这是我们拥有的实体

          【讨论】:

          • 谢谢,工作。为什么 UUID 没有转换成任何东西?它应该是这样还是一个错误?
          【解决方案7】:

          这是针对 Hibernate (5.x) 版本的

          调用返回 JSON 字符串/对象的数据库函数

          为此使用unwrap(org.hibernate.query.NativeQuery.class).addScalar() 方法相同。

          示例如下(Spring & Hibernate):

          @PersistenceContext
          
          EntityManager em;
          
          @Override
          
              public String getJson(String strLayerName) {
          
                  String *nativeQuery* = "select fn_layer_attributes(:layername)";
          
                  return em.createNativeQuery(*nativeQuery*).setParameter("layername", strLayerName).**unwrap(org.hibernate.query.NativeQuery.class).addScalar**("fn_layer_attributes", **new JsonNodeBinaryType()**) .getSingleResult().toString();
          
              }
          
          

          【讨论】:

            【解决方案8】:

            如果您有本机 SQL 查询,则通过向查询添加强制转换来修复它。

            示例

            CAST('yourString' AS varchar(50)) as anyColumnName
            

            就我而言,它对我有用。

            【讨论】:

              【解决方案9】:

              如果您使用的是 Postgres,请检查您是否没有 Abstime 类型的列。 Abstime 是 JPA 无法识别的内部 Postgres 数据类型。在这种情况下,如果您的业务要求允许,使用 TO_CHAR 可以转换为文本。

              【讨论】:

              • 我面临与此处提到的相同的问题。还有其他解决方案吗?它使我无法进行星号查询。
              【解决方案10】:

              当您使用 Hibernate 并返回 void 函数时,也会发生这种情况。至少带有 postgres。它不知道如何处理空虚。我最终不得不将我的 void 更改为 return int。

              【讨论】:

                【解决方案11】:

                我得到了同样的错误,因为我的查询返回了一个 UUID 列。为了解决这个问题,我通过“cast(columnName as varchar)”之类的查询将 UUID 列作为 varchar 类型返回,然后它就起作用了。

                例子:

                public interface StudRepository extends JpaRepository<Mark, UUID> {
                
                    @Modifying
                    @Query(value = "SELECT Cast(stuid as varchar) id, SUM(marks) as marks FROM studs where group by stuid", nativeQuery = true)
                    List<Student> findMarkGroupByStuid();
                
                    public static interface Student(){
                        private String getId();
                        private String getMarks();
                    }
                }
                

                【讨论】:

                  【解决方案12】:

                  在我的情况下,问题是,当我在我的用户类中设置我的存储过程时,我忘记添加 resultClasses 属性。

                  @NamedStoredProcedureQuery(name = "find_email",
                                  procedureName = "find_email", resultClasses = User.class, //<--I forgot that. 
                                  parameters = {
                                      @StoredProcedureParameter(mode = ParameterMode.IN, name = "param_email", type = String.class)
                                  }),
                  

                  【讨论】:

                    【解决方案13】:

                    对于使用旧休眠 (3.x) 版本遇到此错误的任何人:

                    不要用大写字母写返回类型。 hibernate 类型实现映射使用小写返回类型并且不转换它们:

                    CREATE OR REPLACE FUNCTION do_something(param varchar)
                        RETURNS integer AS
                    $BODY$
                    ...
                    

                    【讨论】:

                      【解决方案14】:

                      这里的答案基于来自 SubOptimal 的评论:

                      错误信息实际上是说一个列类型不能被hibernate映射到一个数据库类型。 就我而言,它是我在某些实体中用作主键的java.util.UUID 类型。只需应用注解@Type(type="uuid-char")(对于postgres @Type(type="pg-uuid")

                      【讨论】:

                      • 如果您仅在 HSQLDB 的测试环境中遇到异常 - 请查看 stackoverflow.com/questions/1007176/…
                      • 我同意 Lu55 。除非确实有必要,否则不应添加 @Type 注释。但我并不真正同意链接问题中提供的解决方案(也许它们太旧了?)。因此,我用自己的解决方案创建了一个帖子:stackoverflow.com/questions/1007176/…
                      • 或者在您的查询字符串中,您也可以像这样对 Varchar 进行强制转换:CAST(table_name.column_name as VARCHAR) AS table_name
                      【解决方案15】:

                      请检查是否某些列返回许多在查询中具有未知类型

                      eg : '1' as column_name 可以有未知类型

                      and 1 as column_name is Integer是正确的一个。

                      这件事对我有用。

                      【讨论】:

                      • 我有一个带有我自己的 SqlResultMapping 的本机查询,这就是问题所在,通过向查询 ''CAST('staticstring' AS varchar(50)) 作为 columnmappingname 添加强制转换来修复它跨度>
                      • 是的,您必须在 QUERY 中使用此 CAST 函数才能将类型转换为适当的 DataType。
                      【解决方案16】:

                      有时当您调用 sql 过程/函数时,可能需要返回一些内容。您可以尝试返回 void:RETURN; 或字符串(这对我有用):RETURN 'OK'

                      【讨论】:

                      • 我猜 RETURN 1 会很快。
                      【解决方案17】:

                      还有另一个常见的用例抛出此异常。调用返回void的函数。欲了解更多信息和解决方案,请转到here

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2018-03-08
                        • 2018-12-04
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-08-08
                        相关资源
                        最近更新 更多