Full MCVE is at the bottom of this post.
I am trying to run a very basic Hibernate example as I work through a tutorial. However, I am receiving the following error: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
:
Exception in thread "main" java.lang.ExceptionInInitializerError
at hibernateTutorial.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:50)
at hibernateTutorial.util.HibernateUtil.getSessionFactory(HibernateUtil.java:30)
at hibernateTutorial.main.HibernateMain.main(HibernateMain.java:21)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709)
at hibernateTutorial.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:47)
... 2 more
Caused by: org.vibur.dbcp.ViburDBCPException: java.lang.NullPointerException
at org.vibur.dbcp.ViburDBCPDataSource.start(ViburDBCPDataSource.java:233)
at org.hibernate.vibur.internal.ViburDBCPConnectionProvider.configure(ViburDBCPConnectionProvider.java:57)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 15 more
Caused by: java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:460)
at java.util.Properties.setProperty(Properties.java:166)
at org.vibur.dbcp.pool.Connector$Builder$Driver.<init>(Connector.java:66)
at org.vibur.dbcp.pool.Connector$Builder$Driver.<init>(Connector.java:56)
at org.vibur.dbcp.pool.Connector$Builder.buildConnector(Connector.java:48)
at org.vibur.dbcp.ViburDBCPDataSource.doStart(ViburDBCPDataSource.java:248)
at org.vibur.dbcp.ViburDBCPDataSource.start(ViburDBCPDataSource.java:226)
... 24 more
My database is on a Microsoft SQL Server 2017 instance that uses Windows Authentication. I have added both the MSSQL JDBC (v6.4.0) updated IntelliJ with the -Djava.library.path
VM option so that sqljdbc_auth.dll
(required for Windows Authentication) is accessible.
From what I can tell in my research into this ambiguous error message, it could have many different causes, but ultimately boils down to just not being able to connect to the database somehow. Most of the other Q&A I've found seems to be specific to other databases or SQL Server that doesn't use Windows Authentication.
I have copied the JDBC URL directly from my datasource config in IntelliJ so I know that it is correct and works properly in the IDE.
What else is required to properly configure Hibernate to connect to SQL Server?
HibernateMain.java
:
package hibernateTutorial.main;
import hibernateTutorial.model.Employee;
import hibernateTutorial.util.HibernateUtil;
import org.hibernate.Session;
import java.time.LocalDateTime;
public class HibernateMain {
public static void main(String[] args) {
Employee emp = new Employee();
emp.setName("Nathan");
emp.setRole("CEO");
emp.setInsertTime(LocalDateTime.now());
// **********************************************************************************************
// Get Session
// **********************************************************************************************
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// **********************************************************************************************
// Start transaction
// **********************************************************************************************
session.beginTransaction();
// **********************************************************************************************
// Save the model object
// **********************************************************************************************
session.save(emp);
// **********************************************************************************************
// Commit the transaction
// **********************************************************************************************
session.getTransaction().commit();
System.out.println("Employee ID: " + emp.getId());
// **********************************************************************************************
// Terminate the session factory or the program won't end
// **********************************************************************************************
HibernateUtil.getSessionFactory().close();
}
}
HibernateUtil.java
:
package hibernateTutorial.util;
import hibernateTutorial.model.Employee1;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import java.util.Properties;
public class HibernateUtil {
// **********************************************************************************************
// XML-based configuration
// **********************************************************************************************
private static SessionFactory sessionFactory;
// **********************************************************************************************
// Annotation-based configuration
// **********************************************************************************************
private static SessionFactory sessionAnnotationFactory;
// **********************************************************************************************
// Property-based configuration
// **********************************************************************************************
private static SessionFactory sessionJavaConfigFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
private static SessionFactory buildSessionFactory() {
try {
// **********************************************************************************************
// Create the SessionFactory from hibernate.cfg.xml
// **********************************************************************************************
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable e) {
System.err.println("Initial SessionFactory creation failed. " + e);
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionAnnotationFactory() {
if (sessionAnnotationFactory == null) sessionAnnotationFactory = buildSessionAnnotationFactory();
return sessionAnnotationFactory;
}
private static SessionFactory buildSessionAnnotationFactory() {
try {
// **********************************************************************************************
// Create the SessionFactory from hibernate-annotation.cfg.xml
// **********************************************************************************************
Configuration configuration = new Configuration();
configuration.configure("hibernate-annotation.cfg.xml");
System.out.println("Hibernate Annotation configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Annotation serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable e) {
System.err.println("Initial SessionFactory creationg failed." + e);
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionJavaConfigFactory() {
if (sessionJavaConfigFactory == null) sessionJavaConfigFactory = buildSessionJavaConfigFactory();
return sessionJavaConfigFactory;
}
private static SessionFactory buildSessionJavaConfigFactory() {
try {
Configuration configuration = new Configuration();
//Create Properties, can be read from property files too
Properties props = new Properties();
props.put("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
props.put("hibernate.connection.url", "jdbc:sqlserver://FADBOKT2493V\\KRAFTLAKEODB:51678;database=Dev_RepAssistDB;integratedSecurity=true");
props.put("hibernate.current_session_context_class", "thread");
configuration.setProperties(props);
//we can set mapping file or class with annotation
//addClass(Employee1.class) will look for resource
// com/journaldev/hibernate/model/Employee1.hbm.xml (not good)
configuration.addAnnotatedClass(Employee1.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Java Config serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
}
Employee.java
:
package hibernateTutorial.model;
import java.time.LocalDateTime;
public class Employee {
private int id;
private String name;
private String role;
private LocalDateTime insertTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public LocalDateTime getInsertTime() {
return insertTime;
}
public void setInsertTime(LocalDateTime insertTime) {
this.insertTime = insertTime;
}
}
Employee1.java
:
package hibernateTutorial.model;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "tmp_employees",
uniqueConstraints =
{@UniqueConstraint(columnNames = {"id"})})
public class Employee1 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, unique = true, length = 11)
private int id;
@Column(name = "name", length = 20, nullable = true)
private String name;
@Column(name = "role", length = 20, nullable = true)
private String role;
@Column(name = "insert_time", nullable = true)
private LocalDateTime insertTime;
}
employee.hbm.xml
:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernateTutorial.model.Employee" table="tmp_employees">
<id name="id" type="int">
<column name="id"/>
<generator class="increment"/>
</id>
<property name="name" type="java.lang.String">
<column name="name"/>
</property>
<property name="role" type="java.lang.String">
<column name="role"/>
</property>
<property name="insertTime" type="java.time.LocalDateTime">
<column name="insert_time"/>
</property>
</class>
</hibernate-mapping>
hibernate.cfg.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://servername:port;
database=test_db;integratedSecurity=true
</property>
<!-- Connection Pool Size -->
<property name="hibernate.connection.pool_size">5</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Outputs the SQL queries, should be disabled in Production -->
<property name="hibernate.show_sql">true</property>
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
<!-- mapping file, we can use Bean annotations too -->
<mapping resource="hibernateTutorial/employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernate-annotation.cfg.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver:servername:port;database=test_db;integratedSecurity=true</property>
<!-- Connection Pool Size -->
<property name="hibernate.connection.pool_size">5</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Outputs the SQL queries, should be disabled in Production -->
<property name="hibernate.show_sql">true</property>
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
<!-- mapping with model class containing annotations -->
<mapping class="hibernateTutorial.model.Employee1"/>
</session-factory>
</hibernate-configuration>