Hibernate with Sql Server fails for nvarchar field with "No Dialect mapping ..."
I am using Hibernate JPA-Implementation to access our SQL Server 2012 database.
When I try to select a field nvarchar
in my own query, I get a "No dialectical display for JDBC type: -9" exception.
It looks like No Dialect mapping for JDBC type: -9 with Hibernate 4 and SQL Server 2012, or No Dialect mapping for JDBC type: -9 , but I couldn't find a solution for me there (both don't use JPA).
My database setup:
CREATE TABLE NvarcharExample(
exampleField nvarchar(20) PRIMARY KEY
)
INSERT INTO NvarcharExample(exampleField) VALUES ('hello')
My code:
import java.io.IOException;
import javax.persistence.*;
@Entity
class NvarcharExample {
@Id
public String exampleField;
}
public class NvarcharTest {
public static void main(String[] args) throws IOException, InterruptedException {
String queryString = "SELECT e.exampleField FROM NvarcharExample e";
// establish connection
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistenceUnit");
try {
EntityManager entityManager = entityManagerFactory.createEntityManager();
// access data using JPQL
entityManager.createQuery(queryString).getResultList(); // works
// access data using SQL (native query)
entityManager.createNativeQuery(queryString).getResultList(); // fails
} finally {
entityManagerFactory.close();
}
}
}
My persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="persistenceUnit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- database connection settings -->
<property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://<servername>:<port>;databaseName=<databasename>" />
<property name="javax.persistence.jdbc.user" value="<user>" />
<property name="javax.persistence.jdbc.password" value="<password>" />
</properties>
</persistence-unit>
</persistence>
With sql logging support, I am getting this output in my console
select nvarcharex0_.exampleField as col_0_0_ from NvarcharExample nvarcharex0_
SELECT e.exampleField FROM NvarcharExample e
I use
-
hibernate-core-4.3.10.Final.jar
-
hibernate-entitymanager-4.3.10.Final.jar
-
hibernate-jpa-2.1-api-1.0.0.Final.jar
-
hibernate-commons-annotations-4.0.5.Final.jar
-
sqljdbc41.jar
What I have tried:
- using
varchar
insteadnvarchar
makes it work, but I neednvarchar
- using jpql instead of sql works (see my example code) but i need my own query
- I tried
sqljdbc4.jar
in versions 4.0 and 4.1 and I triedsqljdbc41.jar
- I will introduce a subclass of the SQL Server Dialer class but had no success with this
- I added
<property name="dialect" value="org.hibernate.dialect.SQLServerDialect" />
to minepersistence.xml
(right behind the password property) - I added
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
to mypersistence.xml
- I changed the save provider to
<provider>org.hibernate.ejb.HibernatePersistence</provider>
source to share
I managed to solve this problem by subclassing SQLServerDialect:
package packagename;
import java.sql.Types;
public class SqlServerDialectWithNvarchar extends org.hibernate.dialect.SQLServerDialect {
public SqlServerDialectWithNvarchar() {
registerHibernateType(Types.NVARCHAR, 4000, "string");
}
}
and referring to it in mine persistence.xml
:
<property name="hibernate.dialect" value="packagename.SqlServerDialectWithNvarchar" />
PS: I found the issue report at https://hibernate.atlassian.net/browse/HHH-9750 describing similar behavior and solution (for Oracle databases).
source to share
Using the attribute @Nationalized
helped me map String
to nvarchar for MS SQL 2012 without subclassing dialects.
At the same time, setting the property hibernate.use_nationalized_character_data
to true did not work for me.
For more information, see the docs National Character Types .
source to share