JPA SQL Server 没有 JDBC 类型的方言映射:-9

Posted

技术标签:

【中文标题】JPA SQL Server 没有 JDBC 类型的方言映射:-9【英文标题】:JPA SQL Server No Dialect mapping for JDBC type: -9 【发布时间】:2015-01-18 07:07:18 【问题描述】:

我正在编写类似的原生查询

Query query = 
  entityManagerUtil.getEntityManager().createNativeQuery("SELECT c.NodeID,c.Code,c.Name FROM COM_Location c");    
query.getResultList();

但它不适合我......

我正在使用 JPA、MSSQL Server 2008 和 Spring。当我尝试使用 pojo 类编写 JPA 查询但它无法执行本机查询时,它工作正常。

我在persistance.xml 中的配置是这样的

<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>

有人建议我解决问题

我的堆栈跟踪说...

org.springframework.orm.jpa.JpaSystemException: org.hibernate.MappingException: No Dialect mapping for JDBC type: -9; nested exception is javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: -9
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311)
    at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
    at com.iconma.carz.daoimpl.SecurityDaoImpl.getAllLocations(SecurityDaoImpl.java:40)
    at com.iconma.carz.serviceimpl.SecurityServiceImpl.getAllLocations(SecurityServiceImpl.java:31)
    at com.iconma.carz.controllers.SecurityController.getLocations(SecurityController.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: -9
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:255)
    ... 37 more
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -9
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:77)
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:100)
    at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:375)
    at org.hibernate.loader.custom.CustomLoader$Metadata.getHibernateType(CustomLoader.java:590)
    at org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor.performDiscovery(CustomLoader.java:516)
    at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:532)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1962)
    at org.hibernate.loader.Loader.doQuery(Loader.java:802)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:316)
    at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1842)
    at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
    at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:157)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:246)
    ... 37 more

【问题讨论】:

发布完整的错误堆栈跟踪 也许您应该尝试使用SQLServer2008Dialect,因为SQLServerDialect 用于SQL Server 2000。 @Chaitanya hi chaitanya,我用总堆栈跟踪编辑了我的帖子 @MarkRotteveel 我什至通过将方言更改为 2008 来尝试它,但它不起作用...... 【参考方案1】:

首先,您必须定义要使用的方言类名称: 在 hibernate.cfg.xml 添加你自己的类地址

<property name="hibernate.dialect">com.nhl.dao.SQlServerDBDialect</property>

然后在下面创建新的类

package com.nhl.dao;
import java.sql.Types;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.type.StandardBasicTypes;

public class SQlServerDBDialect extends SQLServerDialect 

    public SQlServerDBDialect() 
        super();
        registerHibernateType(Types.NCHAR, StandardBasicTypes.CHARACTER.getName()); 
        registerHibernateType(Types.NCHAR, 1, StandardBasicTypes.CHARACTER.getName());
        registerHibernateType(Types.NCHAR, 255, StandardBasicTypes.STRING.getName());
        registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
        registerHibernateType(Types.LONGNVARCHAR, StandardBasicTypes.TEXT.getName());
        registerHibernateType(Types.NCLOB, StandardBasicTypes.CLOB.getName());

    

【讨论】:

这是针对整个代码中此问题的实际修复,无需强制转换查询列数据类型。通过扩展 Hibernate 方言来映射适当的数据类型将不再需要基于强制转换的解决方法。 +1 也为我工作。真的很好的解决方案。 @user1903224 这个答案应该被标记为接受。 在 hibernate 3 中,我已经有了一个带有 registerColumnType 的自定义方言,但需要 registerHibernateType 才能通过本机查询选择 nvarchar 列。很好的答案。【参考方案2】:

类型-9 是java.sql.Types.NVARCHAR。查看https://github.com/hibernate/hibernate-orm/tree/master/hibernate-core/src/main/java/org/hibernate/dialect 上SQLServerDialect 变体的来源,没有nvarchar 列的映射。

您可能想尝试定义自己的方言,该方言还注册了各种NVARCHAR-like 定义:

public class SQLServer2008DialectWithNvarchar extends SQLServer2008Dialect 
    public SQLServer2008DialectWithNvarchar () 
        registerColumnType( Types.NCLOB, "nvarchar(MAX)" );
        registerColumnType( Types.LONGNVARCHAR, "nvarchar(MAX)" );
        registerColumnType( Types.NVARCHAR, "nvarchar(MAX)" );
        registerColumnType( Types.NVARCHAR, 4000, "nvarchar($1)" );
    

我基于SQLServer2005DialectVARCHAR 的定义。您可能需要将此类放入 org.hibernate.dialect 包中(或者至少我似乎记得如果您不这样做会有问题)。

注意:我还没有实际测试过这个!

【讨论】:

感谢您的快速回复...我也尝试过这种方式,将此类作为方言,但仍然没有成功 @user1903224 你确定你真的在使用这个新方言吗? 是的,我只在此处使用该类是我的示例公共类 SQLServerDialectOverrider extends SQLServer2008Dialect public SQLServerDialectOverrider() super(); registerColumnType( Types.NCLOB, "nvarchar(MAX)" ); registerColumnType( Types.LONGNVARCHAR, "nvarchar(MAX)" ); registerColumnType( Types.NVARCHAR, "nvarchar(MAX)" ); registerColumnType(Types.NVARCHAR, 4000, "nvarchar($1)" );在我的persistance.xml 中,我保留了这个 【参考方案3】:

我也面临同样的问题,所以我进行了研发,并得到了解决方案,如 Do explicit cast like cast(t2.name as varchar),它对我有用。

cast(t2.name as varchar)

检查此网址。 http://www.coderanch.com/t/565413/ORM/databases/Dialect-mapping-JDBC-type

【讨论】:

这也是一个解决方案,但它似乎并不总是有效。我什至将我的 id 转换为 varchar,但直到我没有使用 @Ebrahim Amini Sharifi 解决方案后问题才消失【参考方案4】:

我也有类似的问题,我的sql是这样的

Query nmspQuery = em.createNativeQuery("select aster from MyTable where my_column = 1001")

Oracle 11g 中 PRODUCT_NODE_ONIX_TYPE 的数据类型是 nvarachar2

我通过将值 asr 转换为 to_char 来修复它。 这很好用

Query nmspQuery = em.createNativeQuery("select TO_CHAR(aster) from MyTable where my_column = 1001")

【讨论】:

【参考方案5】:

您必须扩展方言,并在构造函数中为 N* JDBC 类型注册适当的 Hibernate 类型:

public class MyDialect extends SomeOfTheProvidedDialects 

    public MyDialect() 
        registerHibernateType(Types.NCHAR, StandardBasicTypes.CHARACTER.getName());
        registerHibernateType(Types.NCHAR, 1, StandardBasicTypes.CHARACTER.getName());
        registerHibernateType(Types.NCHAR, 255, StandardBasicTypes.STRING.getName());
        registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
        registerHibernateType(Types.LONGNVARCHAR, StandardBasicTypes.TEXT.getName());
        registerHibernateType(Types.NCLOB, StandardBasicTypes.CLOB.getName());
    

经过测试,工作正常。

他们应该已经将这些添加到 Hibernate 源代码中(在 org.hibernate.dialect.Dialect 类中)...

【讨论】:

以上是关于JPA SQL Server 没有 JDBC 类型的方言映射:-9的主要内容,如果未能解决你的问题,请参考以下文章

JPA javax.persistence.PersistenceException:org.hibernate.MappingException:没有 JDBC 类型的方言映射:-101

Jpa Join 查询与来自两个表的数据,org.hibernate.MappingException:没有 JDBC 类型的方言映射:2002

使用 JDBC 将用户定义的表类型传递给 SQL Server 存储过程

使用 JDBC 将用户定义的表类型传递给 SQL Server 存储过程

springboot和jpa使用的数据源怎么用

jdbc.SQLServerException:将数据导出到 Azure SQL Server 时找不到数据类型“TEXT”