I am hoping someone can help me. My database connection keeps getting closed and will not reopen so I am having to restart my application every few hours.
I have seen other answers here and have tried implementing them but they dont seem to make any difference. My JDBC url has autoReconnect=true and I am using hibernate with a c3p0 connection pool.
Any help would be great!
Hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/devenv38?autoReconnect=true</property>
<property name="hibernate.connection.username">devenv38</property>
<property name="hibernate.connection.password">devenv38</property>
<property name="hibernate.connection.autoReconnect">true</property>
<property name="hibernate.connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Use the C3P0 connection pool provider -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="c3p0.acquire_increment">5</property>
<property name="c3p0.max_size">500</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.idleConnectionTestPeriod">120</property>
<property name="c3p0.initialPoolSize">25</property>
<property name="c3p0.min_size">25</property>
<property name="c3p0.numHelperThreads">15</property>
<property name="c3p0.timeout">0</property> <!-- seconds -->
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- resources -->
<mapping class="entities.Story" />
<mapping class="entities.User" />
</session-factory>
Database Connection Class
public class DatabaseConnection
{
static SessionFactory sf;
private DatabaseConnection()
{
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
sf = configuration.buildSessionFactory(sr);
}
public static Session getSession()
{
if (sf == null)
{
new DatabaseConnection();
}
return sf.openSession();
}
}
Example usage
Session session = DatabaseConnection.getSession();
Transaction txn = session.beginTransaction();
User user = new User();
user.setUsername("JUNIT USER 1");
user.setEmail("test#test.com");
user.setPassword("Test Password");
session.save(user);
txn.commit();
Related
I am using a 5.4.15.Final version of hibernate. When I am running my application in create mode it is not dropped and create the tables. Is there any way I can do it? I remember I was able to do the same in older version(don't exactly remember the version). My hibernate.cfg.xml file is below:
hibernate.cfg.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "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.connection.url">jdbc:postgresql://localhost:5432/test</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.pool_size">5</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.default_schema">test</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="output.record.batch.size">10</property>
<property name="javax.persistence.schema-generation.create-source">metadata</property>
<property name="javax.persistence.schema-generation.scripts.action">create</property>
<property name="javax.persistence.schema-generation.database.action">create</property>
<property name="hibernate.hbm2dll.create_namespaces">true</property>
<property name="javax.persistence.schema-generation.scripts.create-target">sql/executors_create.sql</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL81Dialect</property>
</session-factory>
</hibernate-configuration>
I am creating the sessionFactory object as below:
SessionFactory sessionFactory = new Configuration().configure().addAnnotatedClass(Test.class).buildSessionFactory();
Is there any way to solve this?
I am getting org.hibernate.HibernateException: The internal connection pool has reached its maximum size and no connection is currently available! I believe the problem is due to incorrect session handling. Can anyone suggest the correct way?
This is my Service class.
#Service
public class DataService {
#Autowired
private SessionFactory sessionFactory;
public User createUser(User newUser) {
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(newUser);
session.getTransaction().commit();
session.close();
return newUser;
}
public User findUser(UUID userId) {
Session session = sessionFactory.openSession();
session.beginTransaction();
try {
return session.get(User.class, userId);
} finally {
session.close();
}
}
}
Below is my Hibernate Configuration. I think my configuration is correct. My Session instantiation and closing in-service class is wrong.
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/rest_database?useSSL=false</property>
<property name="connection.username">admin</property>
<property name="connection.password">admin</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>
<mapping class="com.in.models.User" />
</session-factory>
</hibernate-configuration>
In my hibernate.cfg.xml connection pool size was 1.
<property name="connection.pool_size">1</property>
My db query browser(DBeaver) was already connected to my database, hence when I was trying to save the object, it was giving the hibernate exception - no connection available.
When I increased the connection pool size to 2 in hibernate.cfg.xml. Exception got resolved, as database allowed 2 connections.
<property name="connection.pool_size">2</property>
So I have multiple pluggable databases (PDBs) and I want to connect to any one of them dynamically using Hibernate. How do I achieve such functionality?
To connect to PDB1 (and likewise for other PDBs), I have:
protected void setupPdb1() {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("hibernate-1.cfg.xml") // configures settings from hibernate.cfg.xml
.build();
try {
sessionFactory1 = new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Exception ex) {
StandardServiceRegistryBuilder.destroy(registry);
throw new RuntimeException(ex);
}
}
My hibernate config file corresponding to PDB1 is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:oracle:thin:#//localhost:1521/pdb1.oradev.oraclecorp.com</property>
<property name="connection.username">test</property>
<property name="connection.password">password12</property>
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="current_session_context_class">thread</property>
<mapping class="net.codejava.hibernate.Book" />
</session-factory>
</hibernate-configuration>
The issue with this approach is there is one config file for each PDB. How do I dynamically select the PDB to connect to using Hibernate?
it depends on your strategy, what is the trigger to switch database ?
I'm an Hibernate beginner user, I created a very simple application to test it !
But I get this error in the console :
Initial SessionFactory creation failed.org.hibernate.HibernateException: Dialect class not found: org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect
Exception in thread "main" java.lang.ExceptionInInitializerError
at util.HibernateUtil.buildSessionFactory(HibernateUtil.java:20)
at util.HibernateUtil.<clinit>(HibernateUtil.java:10)
at DAO.services.addProduit(services.java:9)
at test.main(test.java:11)
Caused by: org.hibernate.HibernateException: Dialect class not found: org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect
at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:81)
at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:42)
at org.hibernate.cfg.SettingsFactory.determineDialect(SettingsFactory.java:422)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:128)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at util.HibernateUtil.buildSessionFactory(HibernateUtil.java:15)
... 3 more
My Test class :
import DAO.services;
import DAO.Produit;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
services s = new services();
Produit p = new Produit("PC","Sony Vaio",(double )7500);
s.addProduit(p);
}
}
Hibernate.cfg.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated file - Do not edit! -->
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<!-- User / Password -->
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- Database Settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- for performance reasons changed to MyISAM from org.hibernate.dialect.MySQLInnoDBDialect -->
<property name="dialect">org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect</property>
<property name="connection.url">jdbc:mysql://localhost:3306/gestProd</property>
<property name="hibernate.connection.CharSet">utf8</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.useUnicode">true</property>
<!-- Database Scheme Auto Update -->
<property name="hbm2ddl.auto">update</property>
<!-- properties -->
<property name="show_sql">true</property>
<property name="use_outer_join">false</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--
<property name="connection.provider_class ">org.hibernate.connection.C3P0ConnectionProvider</property>
-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.generate_statistics">false</property>
<property name="hibernate.cache.use_structured_entries">false</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.timeout">100</property>
<!-- mapping files -->
<mapping resource="DAO/Categorie.hbm.xml"/>
<mapping resource="DAO/Produit.hbm.xml"/>
</session-factory>
</hibernate-configuration>
service.java :
package DAO;
import org.hibernate.Session;
import util.HibernateUtil;
public class services {
public void addProduit(Produit p){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(p);
session.getTransaction().commit();
}
}
AND finally 2 classes for my objects ( Produit and Categorie ) and their Configuration files !
What do you think may be the source of this error ?
Thank you :)
The dialect for MySql with MyISAM(if that is what you have) should be:
org.hibernate.dialect.MySQLMyISAMDialect
There is some questions with my code using hibernate .
My code as follows .
HibernateUtil.java
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
/**
* get sessionFactory
*
* #author YD
*
*/
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
}
/**
* get sessionFactory from singleton pattern
*
* #return
*/
public static SessionFactory getInstance() {
if (sessionFactory == null) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
sessionFactory = cfg.configure().buildSessionFactory(
serviceRegistry);
}
return sessionFactory;
}
}
MainCode to get news in Action
/**
* get my news
*/
public void getNews() {
Session session = HibernateUtil.getInstance().getCurrentSession();
Transaction tx = session.beginTransaction();
// some operation
tx.commit();
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">
mysql_url
</property>
<property name="hibernate.connection.username">my_username</property>
<property name="connection.password">my_password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- c3p0 connection pool -->
<property name="org.hibernate.c3p0.internal.C3P0ConnectionProvider">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">120</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<!-- mapping file -->
<mapping class="my.News />
</session-factory>
</hibernate-configuration>
I also use struts2 in my project. and my project in a web project deploying on tomcat 7.0.57.
The Problem is :
When I open the web page to get news,sometimes I got the Exception:
Struts Problem Report
Struts has detected an unhandled exception:
Messages:
nested transactions not supported
File: org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
Line number: 154
Stacktraces
org.hibernate.TransactionException: nested transactions not supportedorg.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:154)
org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435)
sun.reflect.GeneratedMethodAccessor59.invoke(Unknown Source)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356)
Why?
I know that if I use session.getCurrentSession() ** to operate session, then there is **no necessary to close session. I commit transaction in end every time. How it happened?