I am using Redshift as a DB for my Java Project with Hibernate support. When the Hibernate starts, it tries to create a sequence, which I do not need.
public class HibernateUtil {
private static SessionFactory SESSION_FACTORY;
private static StandardServiceRegistry registry;
public static synchronized SessionFactory getSessionFactory(DataSource dataSource) {
if (SESSION_FACTORY == null) {
try {
Configuration configuration = new Configuration();
Properties settings = new Properties();
settings.put("show_sql", "false");
settings.put("current_session_context_class", "thread");
settings.put("hbm2ddl.auto", "none");
configuration.setProperties(settings);
registry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.applySetting(Environment.DATASOURCE, dataSource)
.build();
SESSION_FACTORY = configuration.buildSessionFactory(registry);
} catch (Exception e) {
log.error("Error creating Session Factory.", e);
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return SESSION_FACTORY; }
}
This is the stack trace.
ERROR [2019-06-07 14:41:40,743] org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl: Could not fetch the SequenceInformation from the database
! com.amazon.support.exceptions.ErrorException: [Amazon](500310) Invalid operation: relation "information_schema.sequences" does not exist;
! ... 52 common frames omitted
! Causing: java.sql.SQLException: [Amazon](500310) Invalid operation: relation "information_schema.sequences" does not exist;
I created a custom Dialect that overrode existing PostgreSqlDialect
public class CustomRedshiftDialect extends PostgreSQL81Dialect {
#Override
public String getQuerySequencesString() {
return null;
}
}
And in the HibernateUtil class or the appropriate XML.
// Hibernate settings equivalent to hibernate.cfg.xml's properties
Properties settings = new Properties();
settings.put("show_sql", "false");
settings.put("current_session_context_class", "thread");
settings.put("hbm2ddl.auto", "none");
settings.put("hibernate.dialect", "com.me.vlimbare.factory.db.CustomRedshiftDialect");
I am trying to fetch data from table I am using following code to fetch data from db.
public List<UserInfoSetting> fetchAll(Long aid) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
List<UserInfoSetting> obj = null;
try {
String hql = "select s from UserInfoSetting s where s.atom.id=:aid ";
Query query = session.createQuery(hql);
query.setParameter("aid", aid);
obj = query.list();
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
return obj;
}
HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
It is showing following exception
root cause
java.lang.NoClassDefFoundError: Could not initialize class business.HibernateUtil
setting.user.UserCommunicationDao.fetchAll(UserCommunicationDao.java:146)
setting.user.UserCommunication.fetchAll(UserCommunication.java:64)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
How to resolve the above problem
This means either you haven't got all the right Hibernate libraries in your class path, or you're not including the classes you've written. If you're coding using Eclipse, find the project settings and add the Hibernate libraries as dependencies for the project.
You will need to add hibernate-core, but quite a few others too.
Maven would help...
And it would help you a lot if you changed the name of your HibernateUtil class: there is a standard Hibernate class with the same name. Although in principle you can have two classes with the same name but in different packages, it'll be likely to cause confusion. (For instance, it's not entirely clear which one it can't find.)
due to the frequently insert event , (it's a chat room program)
it's always occurs "exception : java heap outOfMemory...."
and i think that it's cause from here
here is my correct code
public static boolean saveMethod(String userid,String username,String msg){
Configuration cfg = new Configuration();
cfg.configure(); //here is correct
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Transaction transaction = null;
try{
....jump
transaction = session.beginTransaction();
session.save(saveMsg);
transaction.commit();
return true;
}catch(Exception e){
return false;
}
}
so i change the method to that
Configuration cfg = new Configuration();
cfg.configure();// error here
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Transaction transaction = null;
public static boolean setPublicMsg(String userid,String username,String msg){
//insert
}
Syntax error on token "configure", Identifier expected after this
token
how can i write here ?
or anyone have some idea about the "exception : java heap outOfMemory...." in hibernate?
i'm try to change the tomcat setting, but it's not working
thanks !
Just by looking at your saveMethod(), it looks like you are creating configuration and sessionFactory per each save call. You can simply avoid this.
When your application starts, you can build the sessionFactory once and reuse as much as you need.
For example, you can use a HibernateUtil class to get the sessionFactory as below.
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null ) {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
return sessionFactory;
}
}
Then in your saveMethod() you get the sessionFactory as below.
public static boolean saveMethod(String userid,String username,String msg){
SessionFactory factory = HibernateUtil.getSessionFactory();
// ...
}
I have 2 methods:
public static Ticket issueTicket(User user,Service service,String[] seats) {
Session ticSess= DB.factory.openSession();
ticSess.beginTransaction();
Date d= new Date();
Ticket ticket=new Ticket(d, service, user);
ticSess.save(ticket);
ticSess.getTransaction().commit();
int seatCount=seats.length;
for (int i=0;i<seatCount;i++){
int seatID=Integer.parseInt(seats[i]);
Seat seat=getSeatByID(seatID);
seat.setTicket(ticket);
ticSess.update(seat);
}
return ticket;
}
and,
public static Seat getSeatByID(int seatID) {
Session proSess = DB.factory.openSession();
proSess.beginTransaction();
Seat c = (Seat) (proSess.load(Seat.class, seatID));
proSess.getTransaction().commit();
return c;
}
when I call issueTicket method I get:
illegally attempted to associate a proxy with two open Sessions
and If I close the session in getSeatByID method there will be another error telling that the session is closed. Here is the Stack Trace:
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at ir.ac.shirazu.cse.Terminal.Seat_$$_javassist_9.setTicket(Seat_$$_javassist_9.java)
at ir.ac.shirazu.cse.Database.DB.issueTicket(DB.java:231)
Try closing proSess in getSeatByID() before returning. Currently the Seat indeed remains attached to session opened in getSeatByID().
I got same problem . But after using singleton pattern for session i'm done. I'm using Hibernate 4.2.x.
This is my session class is used to get sessions for DB transactions etc.
public class SessionClass {
static Session session = PoolManager.getSession();
public static Session getSession() {
if (session != null || session.isOpen()) {
return session;
} else {
session = PoolManager.getSession();
return session;
}
}
}
Hibernate Helper Class I'm using.
public class PoolManager {
private static final SessionFactory sessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
I ran into this issue when trying to associate a entity from a Envers Session.
Fixed that by "refreshing" said entity (retrieving it on my non-Envers session via PK fetch) before bubbling it up to my algorithm.
use session.opensession().get(.....).. instead of session.opensession().load(.....)
what if you do a proSess.evict(c) before committing proSess?
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
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();
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:
http://relation.to/Bloggers/HibernateCore40IsFinal
http://relation.to/19942.lace
http://docs.jboss.org/hibernate/core/4.0/devguide/en-US/html/ch07.html#services-registry
http://sourceforge.net/apps/mediawiki/hibernate/index.php?title=Category:Services
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();
}
}
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);
It's as simple as this: the JBoss docs are not 100% perfectly well-maintained. Go with what the JavaDoc says: buildSessionFactory(ServiceRegistry serviceRegistry).
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());
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.
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);
}
}
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 aSessionFactoryImpl` 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.
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();
}
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);
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.");
}
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);
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();
}
}
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();
}
}
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.
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();
Just import following package,
import org.hibernate.cfg.Configuration;