JDBC类型的无Dialect映射:1111

时间:2015-01-28 12:42:07

标签: java mysql spring hibernate jpa

我正在使用MySQL作为数据库的Spring JPA应用程序。我确保所有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 Test跑者认可(我以前因为打字错误而得到例外)。

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

期待您的回答,谢谢!

BTW该应用程序已使用弹簧启动。

17 个答案:

答案 0 :(得分:13)

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

错误消息实际上表示一个列类型无法通过hibernate映射到数据库类型。 在我的例子中,它是我在某些实体中用作主键的java.util.UUID类型。只需应用注释@Type(type="uuid-char")(适用于postgres @Type(type="pg-uuid")

答案 1 :(得分:8)

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

答案 2 :(得分:5)

我遇到了同样的错误,因为我的查询返回了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();
    }
}

答案 3 :(得分:5)

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

我尝试应用这些注释@Type(type =“ uuid-char”)(对于postgres @Type(type =“ pg-uuid”)),但对我而言不起作用。

这对我有用。假设您要使用JPA中的本机查询从表中获取ID和名称。使用字段ID和名称创建一个实体类(例如“用户”),然后尝试将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])));

    }

假设这是我们拥有的实体

答案 4 :(得分:5)

找到触发问题的列

首先,您没有提供实体映射,所以我们可以知道是什么列导致了此问题。例如,它可以是UUIDJSON列。

现在,您正在使用非常古老的休眠方言。 MySQL5Dialect适用于MySQL5。很可能您正在使用更新的MySQL版本。

因此,请尝试改用MySQL8Dialect

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

添加非标准类型

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

public class MySQL8JsonDialect
        extends MySQL8Dialect{

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

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

<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()
);

有关此主题的更多详细信息,请同时查看this article

答案 5 :(得分:3)

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

答案 6 :(得分:0)

就我而言,它是通过添加 columnDefinition 解决的:

@Column(columnDefinition = "json")

答案 7 :(得分:0)

如果使用 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>

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

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

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

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

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

答案 10 :(得分:0)

返回 void 的函数或过程会导致JPA / Hibernate出现问题,因此使用return integer 对其进行更改并在过程末尾调用return 1可能会解决此问题。

SQL类型1111表示字符串。

答案 11 :(得分:0)

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

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

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

以下示例(春季和冬眠):

@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();

    }

答案 12 :(得分:0)

如果您有本机SQL查询,则可以通过在查询中添加强制转换来解决它。

示例

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

对于我来说,它对我有用。

答案 13 :(得分:0)

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

答案 14 :(得分:0)

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

答案 15 :(得分:0)

就我而言,问题在于,当我在User类中设置存储过程时,我忘了添加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)
                }),

答案 16 :(得分:0)

对于任何使用旧的hibernate(3.x)版本获取此错误的人:

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

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