Is the buildSessionFactory() Configuration method deprecated in Hibernate?
JavaHibernateConfigurationDeprecatedBootstrappingJava Problem Overview
When I updated the Hibernate version from 3.6.8 to 4.0.0, I got a warning about deprecated method buildSessionFactory()
in this line:
private static final SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();
the Javadoc recommends using another method
buildSessionFactory(ServiceRegistry serviceRegistry)
but in the documentation I found deprecated variant
Java Solutions
Solution 1 - Java
Yes it is deprecated. Replace your SessionFactory with the following:
In Hibernate 4.0, 4.1, 4.2
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
public static SessionFactory createSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()). buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
> UPDATE:
In Hibernate 4.3 ServiceRegistryBuilder is deprecated. Use the following instead.
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
Solution 2 - Java
Yes, it is deprecated. http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/cfg/Configuration.html#buildSessionFactory() specifically tells you to use the other method you found instead (buildSessionFactory(ServiceRegistry serviceRegistry)
) - so use it.
The documentation is copied over from release to release, and likely just hasn't been updated yet (they don't rewrite the manual with every release) - so trust the Javadocs.
The specifics of this change can be viewed at:
- Source code: https://github.com/hibernate/hibernate-core/commit/0b10334e403cf2b11ee60725cc5619eaafecc00b
- Ticket: https://hibernate.onjira.com/browse/HHH-5991
Some additional references:
Solution 3 - Java
or
public class Hbutil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static SessionFactory configureSessionFactory() throws HibernateException {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
public static SessionFactory getSessionFactory() {
return configureSessionFactory();
}
}
Solution 4 - Java
Code verified to work in Hibernate 4.3.0. Notice you can remove the XML filename parameter, or else provide your own path there. This is similar to (but typos corrected) other posts here, but this one is correct.
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
Configuration configuration = new Configuration();
configuration.configure("/com/rtw/test/hiber/hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Solution 5 - Java
It's as simple as this: the JBoss docs are not 100% perfectly well-maintained. Go with what the JavaDoc says: buildSessionFactory(ServiceRegistry serviceRegistry)
.
Solution 6 - Java
It is not unusual to find discrepancies between different versions of documentation. Most developers view documentation as a chore, and they tend to put it off.
As a rule of thumb, if the javadoc says one thing and some non-javadoc documentation contradicts it, the chances are that the javadoc is more accurate. Programmers are more likely to keep the javadoc up to date with changes to the code ... because the "source" for the javadoc is in the same file as the code.
In the case of @deprecated
tags, it is a virtual certainty that the javadoc is more accurate. Developers deprecate things after careful consideration ... and (generally speaking) they don't undeprecate them.
Solution 7 - Java
A better way to create SessionFactory object in Latest hibernate release 4.3.0 onward is as follow:
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
applySettings(configuration.getProperties());
SessionFactory factory = configuration.buildSessionFactory(builder.build());
Solution 8 - Java
If you are using Hibernate 5.2 and above then you can use this:
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Creating a registry
registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
// Create the MetadataSources
MetadataSources sources = new MetadataSources(registry);
// Create the Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
//To shut down
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
Solution 9 - Java
TL;DR
Yes, it is. There are better ways to bootstrap Hibernate, like the following ones.
Hibernate-native bootstrap
The legacy Configuration
object is less powerful than using the BootstrapServiceRegistryBuilder
, introduced since Hibernate 4:
final BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder()
.enableAutoClose();
Integrator integrator = integrator();
if (integrator != null) {
bsrb.applyIntegrator( integrator );
}
final BootstrapServiceRegistry bsr = bsrb.build();
final StandardServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder(bsr)
.applySettings(properties())
.build();
final MetadataSources metadataSources = new MetadataSources(serviceRegistry);
for (Class annotatedClass : entities()) {
metadataSources.addAnnotatedClass(annotatedClass);
}
String[] packages = packages();
if (packages != null) {
for (String annotatedPackage : packages) {
metadataSources.addPackage(annotatedPackage);
}
}
String[] resources = resources();
if (resources != null) {
for (String resource : resources) {
metadataSources.addResource(resource);
}
}
final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder()
.enableNewIdentifierGeneratorSupport(true)
.applyImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
final List<Type> additionalTypes = additionalTypes();
if (additionalTypes != null) {
additionalTypes.stream().forEach(type -> {
metadataBuilder.applyTypes((typeContributions, sr) -> {
if(type instanceof BasicType) {
typeContributions.contributeType((BasicType) type);
} else if (type instanceof UserType ){
typeContributions.contributeType((UserType) type);
} else if (type instanceof CompositeUserType) {
typeContributions.contributeType((CompositeUserType) type);
}
});
});
}
additionalMetadata(metadataBuilder);
MetadataImplementor metadata = (MetadataImplementor) metadataBuilder.build();
final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
Interceptor interceptor = interceptor();
if(interceptor != null) {
sfb.applyInterceptor(interceptor);
}
SessionFactory sessionFactory = sfb.build();
JPA bootstrap
You can also bootstrap Hibernate using JPA:
PersistenceUnitInfo persistenceUnitInfo = persistenceUnitInfo(getClass().getSimpleName());
Map configuration = properties();
Interceptor interceptor = interceptor();
if (interceptor != null) {
configuration.put(AvailableSettings.INTERCEPTOR, interceptor);
}
Integrator integrator = integrator();
if (integrator != null) {
configuration.put(
"hibernate.integrator_provider",
(IntegratorProvider) () -> Collections.singletonList(integrator));
}
EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder =
new EntityManagerFactoryBuilderImpl(
new PersistenceUnitInfoDescriptor(persistenceUnitInfo),
configuration
);
EntityManagerFactory entityManagerFactory = entityManagerFactoryBuilder.build();
This way, you are building the EntityManagerFactory
instead of a SessionFactory
. However, the SessionFactory
extends the EntityManagerFactory, so the actual object that's built is a
SessionFactoryImpl` too.
Conclusion
These two bootstrapping methods affect Hibernate behavior. When using the native bootstrap, Hibernate behaves in the legacy mode, which predates JPA.
When bootstrapping using JPA, Hibernate will behave according to the JPA specification.
There are several differences between these two modes:
- How the AUTO flush mode works in regards to native SQL queries
- How the entity Proxy is built. Traditionally, Hibernate did not hit the DB when building a Proxy, but JPA requires throwing an
EntityNotFoundException
, therefore demanding a DB check. - whether you can delete a non-managed entity
> For more details about these differences, check out the JpaCompliance
class.
Solution 10 - Java
public class HibernateSessionFactory {
private static final SessionFactory sessionFactory = buildSessionFactory1();
private static SessionFactory buildSessionFactory1() {
Configuration configuration = new Configuration().configure(); // configuration
// settings
// from
// hibernate.cfg.xml
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
serviceRegistryBuilder.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
return configuration.buildSessionFactory(serviceRegistry);
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
Solution 11 - Java
If anyone here after updating to 5.1 this is how it works
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
MetadataSources sources = new MetadataSources(registry);
Metadata metadata = sources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
instead of the below in hibernate 4.3
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()). buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Solution 12 - Java
public void sampleConnection() throws Exception {
Configuration cfg = new Configuration().addResource("hibernate.cfg.xml").configure();
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(ssrb.build());
Session session = sessionFactory.openSession();
logger.debug(" connection with the database created successfuly.");
}
Solution 13 - Java
I edited the method created by batbaatar above so it accepts the Configuration object as a parameter:
public static SessionFactory createSessionFactory(Configuration configuration) {
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
factory = configuration.buildSessionFactory(serviceRegistry);
return factory;
}
In the main class I did:
private static SessionFactory factory;
private static Configuration configuration
...
configuration = new Configuration();
configuration.configure().addAnnotatedClass(Employee.class);
// Other configurations, then
factory = createSessionFactory(configuration);
Solution 14 - Java
In Hibernate 4.2.2
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class Test {
public static void main(String[] args) throws Exception
{
Configuration configuration = new Configuration()
.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Users users = new Users();
... ...
session.save(users);
transaction.commit();
session.close();
sessionFactory.close();
}
}
Solution 15 - Java
Tested on 4.2.7 release
package com.national.software.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import com.national.software.dto.UserDetails;
public class HibernateTest {
static SessionFactory sessionFactory;
public static void main(String[] args) {
// TODO Auto-generated method stub
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("user1");
Configuration config = new Configuration();
config.configure();
ServiceRegistry serviceRegistry = (ServiceRegistry) new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
sessionFactory = config.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
}
Solution 16 - Java
here are many APIs deprecated in the hibernate core framework.
we have created the session factory as below:
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
The method buildSessionFactory is deprecated from the hibernate 4 release and it is replaced with the new API. If you are using the hibernate 4.3.0 and above, your code has to be:
-
Configuration configuration = new Configuration().configure();
-
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
-
SessionFactory factory = configuration.buildSessionFactory(builder.build());
Class ServiceRegistryBuilder is replaced by StandardServiceRegistryBuilder from 4.3.0. It looks like there will be lot of changes in the 5.0 release. Still there is not much clarity on the deprecated APIs and the suitable alternatives to use. Every incremental release comes up with more deprecated API, they are in way of fine tuning the core framework for the release 5.0.
Solution 17 - Java
In hibernate 5.3.1
, you can try this:
ServiceRegistry standardRegistry =
new StandardServiceRegistryBuilder().configure().build();
Metadata sources = new MetadataSources(standardRegistry).addAnnotatedClass(MyEntity.class).getMetadataBuilder().build();
SessionFactory sf = sources.buildSessionFactory();
Solution 18 - Java
Just import following package,
import org.hibernate.cfg.Configuration;