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)" );
我基于SQLServer2005Dialect
中VARCHAR
的定义。您可能需要将此类放入 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 中,我保留了这个我也面临同样的问题,所以我进行了研发,并得到了解决方案,如 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 存储过程
jdbc.SQLServerException:将数据导出到 Azure SQL Server 时找不到数据类型“TEXT”