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

Introduction

Here I am going to show you how to resolve issue org.hibernate.mapping.exception: No Dialect mapping for JDBC type that occurs in your Hibernate based application due to some types mismatch between database table column and Java field.

You might have seen similar kind of exception occurred during performing native queries without entity class and this kind of issue may have been occurred in different databases such as MySQL, Oracle, SQL Server, PostgreSQL etc. Depending upon the database vendor you will get error for JDBC types -4, -9, 7 or 2003 etc.

It means that Hibernate is unable to implement a type mapping for database type (for example, table column type float) to Java type (float) though float type is listed in the JDBC reference.

Prerequisites

Oracle Database, Hibernate, JPA, Spring Boot

Example

Here I will create an example how to query Oracle database without entity class using Hibernate JPA and in what situation it throws the exception org.hibernate.MappingException: No Dialect mapping for JDBC type: -9.

In this example I will also show you how to resolve the issue – org.hibernate.MappingException: No Dialect mapping for JDBC type.

I assume that you are using Hibernate JPA with Spring Boot application.

Spring Configuration

Let’s say you have the following configurations for your Oracle database connections and you have defined few beans for DataSource, EntityManager and TransactionManager as shown in the following configuration class.

Make sure your have the correct database URL, user name and password in the following database configurations.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.roytuts.jparepo")
public class OracleDbConfig {
	@Bean
	public DataSource dataSource() throws SQLException {
		OracleDataSource dataSource = new OracleDataSource();
		dataSource.setUser("");
		dataSource.setPassword("");
		dataSource.setURL(
										"jdbc:Oracle:thin:@//:/");
		dataSource.setImplicitCachingEnabled(true);
		dataSource.setFastConnectionFailoverEnabled(true);
		return dataSource;
	}
	@Bean
	public EntityManagerFactory entityManagerFactory() throws SQLException {
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		vendorAdapter.setDatabase(Database.ORACLE);
		vendorAdapter.setShowSql(true);
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		factory.setJpaVendorAdapter(vendorAdapter);
		factory.setPackagesToScan("com.roytuts.model");
		factory.setDataSource(dataSource());
		factory.afterPropertiesSet();
		return factory.getObject();
	}
	@Bean
	public PlatformTransactionManager transactionManager() throws SQLException {
		JpaTransactionManager txManager = new JpaTransactionManager();
		txManager.setEntityManagerFactory(entityManagerFactory());
		return txManager;
	}
}

Spring Repository

Let’s say you have the following DAO class in order to perform database query to fetch something. Notice here I don’t have any Entity class or Spring JpaRepository interface API used. I am using here native query to fetch data from database.

@Repository
public class UserGroupRepo {
	@Autowired
	private EntityManagerFactory entityManagerFactory;
	public String getUserGroup() {
		Query groups = entityManagerFactory.createEntityManager().createNativeQuery(
										"SELECT GROUP_NAME FROM USER_GROUP WHERE EMAIL='someemail@email.com'");
		return (String) groups.getSingleResult();
	}
}

Exception

Now when you call the above getUserGroup() method from other class (service, controller, component, etc.) you will get below exception.

In the next section we will analysis what went wrong with the above code in getUserGroup() method.

SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: -9] with root cause
org.hibernate.MappingException: No Dialect mapping for JDBC type: -9
                at org.hibernate.dialect.TypeNames.get(TypeNames.java:70)
                at org.hibernate.dialect.TypeNames.get(TypeNames.java:101)
                at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:666)
                at org.hibernate.loader.custom.JdbcResultMetadata.getHibernateType(JdbcResultMetadata.java:77)
                at org.hibernate.loader.custom.ScalarResultColumnProcessor.performDiscovery(ScalarResultColumnProcessor.java:45)
                at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:487)
                at org.hibernate.loader.Loader.getResultSet(Loader.java:2125)
                at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1900)
                at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1876)
                at org.hibernate.loader.Loader.doQuery(Loader.java:919)
                at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
                at org.hibernate.loader.Loader.doList(Loader.java:2617)
                at org.hibernate.loader.Loader.doList(Loader.java:2600)
                at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2429)
                at org.hibernate.loader.Loader.list(Loader.java:2424)
                at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:336)
                at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1967)
                at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:322)
                at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125)
                at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606)
                at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:529)
                at com.roytuts.dao.UserGroupRepo.getUserGroup(UserGroupRepo.java:18)
                ...more

What went wrong?

In the above example you see you don’t have any entity class for our USER_GROUP table but we are querying database table directly without using entity class and Spring’s JpaRepository interface.

Therefore Hibernate framework is not able to map the database table’s column data type to Java type. That’s is why you are getting such exception.

Even if we create our custom query, then also you need to use entity class and JpaRepository to query database table in order to get the expected results. But here you are neither using entity class nor JpaRepository interface to query database.

The next step would be to resolve this issue. The answer to this problem is to write a custom dialect and set it to vendorAdapter object using method setDatabasePlatform().

Custom Dialect

Here we I am going to write custom dialect to resolve the issue.

package com.roytuts.dialect;

import java.sql.Types;
import org.hibernate.dialect.Oracle12cDialect;
import org.hibernate.type.StandardBasicTypes;

public class CustomDialectOracle extends Oracle12cDialect {

	public CustomDialectOracle() {
		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());
	}

}

In the above code you see I have extended the class Oracle12cDialect because I am using Oracle 12C, but here you have to extend the class according to your database vendor and version.

Now update the below code snippets.

Replace

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.ORACLE);
vendorAdapter.setShowSql(true);

By

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.ORACLE);
vendorAdapter.setDatabasePlatform("com.roytuts.dialect.CustomDialectOracle");
vendorAdapter.setShowSql(true);

Now executing the query again, you will get the expected result.

Thanks for reading.

One Thought to “org.hibernate.MappingException: No Dialect mapping for JDBC type”

  1. Anand

    Thanks for saving my time, Soumitra. Well explained.

Leave a Comment