I am changing my code from openSession() to getCurrentSession() so it won't create connections at each request.
I have done code in class as:
public Session openSession(boolean current1){
int count = 0;
int MAX_COUNT = 10;
// this.printIdMap();
while( count++ < MAX_COUNT) {
try {
this.session = this.getSessionFactory().getCurrentSession();
this.transaction = this.session.beginTransaction();
this.IncDecCounter(true);
// this.session.getTransaction().commit();
break;
}
catch ( Exception e ) {
this.printIdMap();
e.printStackTrace();
try { this.session.close(); } catch( Exception e1 ) {}
}
}
return this.session;
}
I have checked in multiple places to set property in hibernate.cfg.xml file.
<property name="hibernate.current_session_context_class">thread</property>
I also tried
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
but facing error as
org.hibernate.HibernateException: No CurrentSessionContext configured!
The hibernate version which I am using is 5.4.1
Lets imagine your Hibernate session manager class looks like this
public class HibernateSessionManager {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistryBuilder serviceRegistryBuilder = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties());
return configuration.buildSessionFactory(serviceRegistryBuilder
.buildServiceRegistry());
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Use this property in your configuration file
<property name="hibernate.current_session_context_class">thread</property>
Instead of you currecnt one i.e
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
And get your session with
Session session = HibernateSessionManager.getSessionFactory().openSession();
Related
yeah i know what you think that i didn't try resolve, check other topics etc. I read other topics but anywhere I can't find same problem as my.
Console give me this stacktrace:
20-Dec-2016 20:59:19.482 INFO [http-nio-8080-exec-7]
org.hibernate.cfg.Configuration.configure HHH000042: Configuring from file:
hibernate.cfg.xml
Enitial SessionFactory creation failedorg.hibernate.HibernateException:
could not find file: spring-mvc-angularjs-
master\src\main\java\com\user\springmvcangularjs\hibernate.cfg.xml
Well in first line i got information about that springe configuring from file hibernate.cfg.xml, but when i try connect with database i have error "could not find file".
I try all solutions but any helped me.
My code:
HibernateUtill class
public class HibernateUtil {
private static final SessionFactory ourSessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Enitial SessionFactory creation failed" + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return ourSessionFactory;
}
}
Method in UserService class:
#Override
public void save(User user)
{
HibernateUtil hibernateUtil = new HibernateUtil();
SessionFactory sessFact = hibernateUtil.getSessionFactory();
Session session = sessFact.getCurrentSession();
org.hibernate.Transaction tr = session.beginTransaction();
System.out.println(tr.isActive());
session.save(user);
tr.commit();
sessFact.close();
}
PS I have hibernate.cfg.xml file in spring-mvc-angularjs-master/src/main/java
I'm working over HIbernate 4.3 and I'm getting problems with sessions.. I'm trying to do some operations on database but didnt work properly. Im receiving the message that Session is closed.
My HibernateUtil class that create the session factory:
public class HibernateUtil
{
private static SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory()
{
try
{
if (sessionFactory == null)
{
Configuration configuration = new Configuration().configure(HibernateUtil.class.getResource("/hibernate.cfg.xml"));
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
serviceRegistryBuilder.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
return sessionFactory;
} catch (Throwable ex)
{
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory()
{
return sessionFactory;
}
public static void shutdown()
{
getSessionFactory().close();
}
}
My hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/db?autoReconnect=true</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- Use the C3P0 connection pool. -->
<property name="c3p0.min_size">3</property>
<property name="c3p0.max_size">10</property>
<property name="c3p0.timeout">1800</property>
<!-- Disable second-level cache. -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_minimal_puts">false</property>
<property name="max_fetch_depth">3</property>
<!-- Print SQL to stdout. -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and then re-create schema on SessionFactory build, for testing. -->
<property name="hbm2ddl.auto">create</property>
<!-- Bind the getCurrentSession() method to the thread. -->
<property name="current_session_context_class">thread</property>
<mapping class="model.User"/>
<mapping class="model.Point"/>
<mapping class="model.Layer"/>
<mapping class="model.AddressDatabase"/>
</session-factory>
</hibernate-configuration>
My HibernateListener that starts on the web.xml:
public class HibernateListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
HibernateUtil.getSessionFactory();
}
public void contextDestroyed(ServletContextEvent event) {
HibernateUtil.getSessionFactory().close();
}
}
My DAOFactory of Hibernate:
public class HibernateDAOFactory extends DAOFactory {
public UserDao getUserDao() {
return (UserDao)instantiateDAO(UserDaoImpl.class);
}
private GenericHibernateDao instantiateDAO(Class daoClass) {
try {
GenericHibernateDao dao = (GenericHibernateDao)daoClass.newInstance();
dao.setSession(getCurrentSession());
return dao;
} catch (Exception ex) {
throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
}
}
// You could override this if you don't want HibernateUtil for lookup
protected Session getCurrentSession() {
return HibernateUtil.getSessionFactory().getCurrentSession();
}
}
And my HibernateDAO Factory, that instantiate the DAOs:
public class HibernateDAOFactory extends DAOFactory {
public UserDao getUserDao() {
return (UserDao)instantiateDAO(UserDaoImpl.class);
}
private GenericHibernateDao instantiateDAO(Class daoClass) {
try {
GenericHibernateDao dao = (GenericHibernateDao)daoClass.newInstance();
dao.setSession(getCurrentSession());t
return dao;
} catch (Exception ex) {
throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
}
}
protected Session getCurrentSession() {
return HibernateUtil.getSessionFactory().getCurrentSession();
}
}
Relevant parts of GenericDAO:
public abstract class GenericHibernateDao<T, ID extends Serializable> implements GenericDao<T, ID> {
private Class<T> persistentClass;
private Session session;
#SuppressWarnings("unchecked")
public GenericHibernateDao() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
public void setSession(Session s) {
this.session = s;
}
protected Session getSession() {
if (session == null)
session = HibernateUtil.getSessionFactory().getCurrentSession();
return session;
}
public T create(T entity) {
getSession().save(entity);
return entity;
}
...
When I do sequences of operations on database I got the error.. The code below is a servlet and show how I instantiate my DAO and try to run some operations :
DAOFactory factory = DAOFactory.instance(DAOFactory.HIBERNATE);
userDao = factory.getUserDao();
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction;
User user = new User();
user.setEmail("xxx#gmail.com");
user.setName("xxx");
user = userDao.create(user);
tx.commit(); <-- WORKS FINE
session = HibernateUtil.getSessionFactory().getCurrentSession();
tx = session.beginTransaction;
User user2 = userDao.findByEmail("xxx#gmail.com"); <-- HERE HAPPENS THE ERROR.
I followed theses tutorials:
https://developer.jboss.org/wiki/SessionsAndTransactions
https://community.jboss.org/wiki/GenericDataAccessObjects
I tried to use OpenSesssion instead of getCurrentSession but I got this error on the first action on database:
org.hibernate.HibernateException: save is not valid without active transaction
And when I use the other one, I got the exception that the Sesssion is closed!
Any help will be appreciated.
Regards
We provide db credential in hibernate.cfg.xml as
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">url</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<session-factory>
<hibernate-configuration>
Either we can provide these properties here or in hibernate.properties in classpath. But I want them to come from an external file. I couldn't find a way in hibernate to change the path of default hibernate.properties file.
Please help.
[EDIT]
The method in java which generates sessionFactory object
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
// Create the session factory from hibernate.cfg.xml
Configuration configuration = new Configuration();
StandardServiceRegistryBuilder serviceRegistryBuilder =
new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
return configuration.buildSessionFactory(serviceRegistryBuilder.build());
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Programmatically, you can load XML and properties like this:
public class MyHibernate {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
URL r1 = MyHibernate.class.getResource("/hibernate.cfg.xml");
Configuration c = new Configuration().configure(r1);
try {
InputStream is = MyHibernate.class.getResourceAsStream("/hibernate.properties");
Properties props = new Properties();
props.load(is);
c.addProperties(props);
} catch (Exception e) {
LOG.error("Error reading properties", e);
}
return c.buildSessionFactory();
} catch (Throwable ex) {
LOG.error("Error creating SessionFactory", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Through Spring
You can use a PropertiesFactoryBean to read-in the properties from your file and configure your LocalSessionFactoryBean:
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="hibernateProperties">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">path-to-properties-file</property>
</bean>
</property>
...
</bean>
Hope it be useful.
I have a servlet, running on Tomcat 6, that uses Hibernate 4.1.6 and c3p0 0.9.1.2, and I am getting too much org.hibernate.ResourceClosedException, with the message "This TransactionCoordinator has been closed".
I've already checked that beginTransaction() and rollback() or commit() are done before the thread is reused by another call.
At hibernate.cfg.xml, I have
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:mysql://host/database</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- mappings start here -->
...
</session-factory>
</hibernate-configuration>
and I am using a HibernateUtil.java to create a static sessionFactory for my application and I use it to control my transactions:
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
public static void beginTransaction() {
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
}
public static void commit() {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
}
public static void rollback() {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
}
}
When I start using the database in a servlet, my code is basically this:
try {
HibernateUtil.beginTransaction();
// do stuffs
HibernateUtil.commit();
} catch (RuntimeException e) {
HibernateUtil.rollback();
throw e;
} catch (Exception e) {
HibernateUtil.rollback();
throw e;
}
Where am I doing wrong?
I have closed a session after completing transaction and in the new session i have used the object of previous session, this caused me an 'Transaction Coordinator has been closed'
I have edited the code to use new session object, now the error is resolved
I recently started using hibernate along with c3p0 as the ORM in my application. However, when I close the session factory, the connection pool does not close itself! This is the one and only place in my application where I do anything with a session.
StatelessSession session = null;
Transaction transaction = null;
try {
session = sessionFactory.openStatelessSession();
transaction = session.beginTransaction();
List<Thingy> list = session.getNamedQuery("getAvailableThingy").list();
transaction.commit();
return list;
} catch (Exception error) {
if (transaction != null) {
transaction.rollback();
}
throw error;
} finally {
if (session != null) {
session.close();
}
}
This is my hibernate.cfg.xml configuration file
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="javax.persistence.validation.mode">none</property>
<property name="hibernate.connection.release_mode">after_transaction</property>
<property name="hibernate.c3p0.minPoolSize">1</property>
<property name="hibernate.c3p0.maxPoolSize">2</property>
<property name="hibernate.c3p0.acquireIncrement">1</property>
<property name="hibernate.c3p0.initialPoolSize">1</property>
<property name="hibernate.c3p0.timeout">30</property>
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">5</property>
<property name="hibernate.c3p0.idleConnectionTestPeriod">300</property>
</session-factory>
</hibernate-configuration>
Note that the reason for the very short idle connection it that its the only way I found yet to make my integration tests to pass. They open and close the session factory a lot and thus I always run out of connections. As we are at the beginning of the project, I guess it's not a very sustainable strategy in the long run.
An "interesting" thing to note is that despite the fact that I set the initial connection pool to one, c3p0 still try to open two connection on start. My guess is that there is some kind of hidden session somewhere that don't get closed (but where? beat me).
So how can I get that annoying connection pool to close itself up?
Additional info :
how I create and destroy my session factory
import static com.google.common.base.Preconditions.*;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Provides;
#Singleton
public class PostgisConnection implements Provider<SessionFactory>, AutoCloseable {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final ConnectionInfo connectionInfo;
private SessionFactory sessionFactory = null;
#Inject
public PostgisConnection(ConnectionInfo connectionInfo) {
this.connectionInfo = connectionInfo;
}
public AutoCloseable open() {
checkState(sessionFactory == null, "Connections to postgis are already open");
logger.info("Creating sessionFactory for connection to postgis: {}", connectionInfo.getJdbcUrl());
sessionFactory = newPostgisSessionFactory(connectionInfo);
return this;
}
#Override
public void close() throws Exception {
try {
if (sessionFactory != null) {
logger.info("Closing sessionFactory for postgis: {}", connectionInfo.getJdbcUrl());
sessionFactory.close();
checkState(sessionFactory.isClosed(), "Session factory should be closed at this point");
}
} catch (Exception error) {
logger.error("Error closing SessionFactory", error);
}
}
#Provides
public SessionFactory get() {
return sessionFactory;
}
public static SessionFactory newPostgisSessionFactory(ConnectionInfo connectionInfo) {
Configuration configuration = configurationWith(connectionInfo);
return configuration.buildSessionFactory(registryFrom(configuration));
}
private static Configuration configurationWith(ConnectionInfo connectionInfo) {
Configuration configuration = new Configuration();
setConnectionInfo(connectionInfo, configuration);
configuration.addURL(PostgisConnection.class.getResource("mapping.hbm.xml"));
configuration.configure(PostgisConnection.class.getResource("hibernate.cfg.xml"));
return configuration;
}
private static void setConnectionInfo(ConnectionInfo connectionInfo, Configuration configuration) {
configuration.setProperty("hibernate.connection.url", connectionInfo.getJdbcUrl());
configuration.setProperty("hibernate.connection.username", connectionInfo.getUsername());
configuration.setProperty("hibernate.connection.password", connectionInfo.getPassword());
}
private static ServiceRegistry registryFrom(Configuration configuration) {
return new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
}
}
Hibernate version : 4.1.10.Final
C3p0 version : 0.9.1.2
I had the same issue and successfully used the work-around offered in this bug report:
private void closeSessionFactory(SessionFactory factory) {
if(factory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)factory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
factory.close();
}
You have to reference the hibernate-c3p0-4.x.x jar.
I had the same issue and successfully used the ehnanced (January 2014) work-around offered in this bug report:
private static boolean closeSessionFactoryIfC3P0ConnectionProvider(SessionFactory factory) {
boolean done = false;
if(factory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)factory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
try {
Thread.sleep(2000); //Let give it time...it is enough...probably
} catch (InterruptedException e) {
e.printStackTrace();
}
done = true;
}
factory.close();
}
return done;
}
You have to reference the hibernate-c3p0-4.x.x jar.