Hibernate Connection Leak - mysql

i'm kinda new on web dev, i'm a trainee on a company since last year and i have the following problem:
I'm making a web app with JSF2.3 and Hibernate 5.4.2.Final and c3p0 5.4.2.Final. The thing is everytime i run and go for the login page, i need to check if there is an admin user already registered - i make a count on employee's table based on employee's code - and if there isn't any administrator, then i get a list of country states and render a form register menu.
So, i get the session from the sessionfactory.opensession() in mine HibernateUtil.class, do the count and clear/close the session like the snipet:
public Long retornaLong(String query) throws Exception{
Session session = new HibernateUtil().getSession();
try {
return (Long) session.createQuery(query).getSingleResult();
}finally {
session.clear();
session.close();
}
}
then i get the country states list from
#SuppressWarnings("unchecked")
public List<T> retornaList(String query) throws Exception{
Session session = new HibernateUtil().getSession();
try {
return (List<T>) session.createQuery(query).getResultList();
}finally {
session.clear();
session.close();
}
}
but if i keep refreshing the page (#viewscoped), like 15+ times, eventually i'll get too many connection exception, this doesn't happen if i use one session for both queries. I think there's no enough time for the session to close, causing a connection leak. I want to use one session for each query, can someone help me. Thanks a lot.
My hibernate.cfg.xml
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<!-- properties -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/vetsnpets?useTimezone=true&serverTimezone=UTC</property>
<property name="hibernate.connection.username">vetsNpets</property>
<property name="hibernate.connection.password">123</property>
<property name="hiberante.show_sql">false</property>
<property name="hiberante.format_sql">false</property>
<property name="hbm2ddl.auto">validate</property>
<property name="current_session_context_class">thread</property>
<!-- C3P0 -->
<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">20</property>
<property name="hibernate.c3p0.maxStatements">100</property>
<property name="hibernate.c3p0.maxStatementsPerConnection">5</property>
<property name="hibernate.c3p0.maxIdleTime">2700</property>
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">600</property>
<property name="hibernate.c3p0.acquireIncrement">1</property>

Related

Export Database Table To JSon Using Apache Camel Not Behaving As Expected

I would like to export a table of a database to JSON file with this code using the code listed below, the code runs but splits returned data rows into a file per record not a single file as expected.
Camel's route :
public void configure() throws Exception {
JsonDataFormat jsonFormat = new JsonDataFormat(JsonLibrary.XStream);
jsonFormat.setUnmarshalType(Customer.class);
from("sql: SELECT * FROM assignment01.staff?dataSourceRef=dataSource")
.marshal(jsonFormat)
.to("file:data/test");
}
there is my xml
<bean id="route" class="com.huyqtran.JSonRoute"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="route"/>
</camelContext>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/assignment01?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
I expect that the application just create one JSON file for the whole table.
Tell Camel to append to the file with option fileExist=Append: http://camel.apache.org/file2, eg
.to("file:data/test?fileExist=Append");
or tell the SQL component to return the entire result-set by turning of its iterator, eg useIterator=false
from("sql: SELECT * FROM assignment01.staff?dataSourceRef=dataSource&useIterator=false")

Converting MySQL to H2

I’m working on a project following this code :
Link to download of code: https://bitbucket.org/vrto/spring-tutorial/get/a66534cc7033.zip
Now what I really want, instead of MySQL, is to have an embedded database running HSQL or H2. So I’ve working on my own project trying to implement such a system.
In the tutorial code, he creates a database. And then h2 + hibernates creates the future tables for him – so it would be create if I could do this without having to have an sql schema or anything to set it up.
So I’ve gotten rid of mySql maven dependencies and am working on replacing the persistence-beans.xml
Now I have to replace my dataSource with a relevant h2 or hsql version.
So this is what I’ve gotten.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name ="driverClassName" value = "org.h2.driver"/>
<property name = "url" value ="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
<property name = "username" value = "sa" />
<property name = "password" value = "" />
</bean>
// I also tried this (but again, having a schema with his code is tricky I’ve found
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
But it fails upon running HibernateConfigurationTest.Java (and in extension – all the others)
Any help would be greatly appreciated.
I've managed to get this test work with my schema
#ContextConfiguration(locations = "/persistence-beans.xml")
public class HibernateConfigurationTest extends AbstractJUnit4SpringContextTests {
#Autowired
private SessionFactory sessionFactory;
#Test
public void testHibernateConfiguration() {
// Spring IOC container instantiated and prepared sessionFactory
assertNotNull (sessionFactory);
}
}
the rest tests are in this link : http://vrtoonjava.wordpress.com/2012/06/17/part-3-dao-and-service-layer/

connection.createStatement in Spring-managed datasource never return

This is very strange in my RESTful WS development. I am using Tomcat 7 with Jersey 1.8, Spring 2.5 and MySQL database.
I defined two data sources like this:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="jdbc/MAINDB" />
<property name="resourceRef" value="true" />
</bean>
<bean id="orderDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="jdbc/ORDERS" />
<property name="resourceRef" value="true" />
</bean>
and inject one data source into the servlet context like this:
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="orderData">
<ref bean="orderDataSource" />
</entry>
</map>
</property>
</bean>
and this code:
orderDataSource = (DataSource) sc.getServletContext().getAttribute("orderData");
Order ord = new Order();
Statement stmt = null;
try {
stmt = orderDataSource.getConnection().createStatement();
} catch (SQLException ex) {
Logger.getLogger(OrdersResource.class.getName()).log(Level.SEVERE, null, ex);
}
gets executed 6 or 7 times flawlessly and from the 8th request, it gets stall at createStatement() line and never return or throw any exception!
However, all other resources API from MAINDB still works very well.
Anyone knows what's happening?
Why are you bothering with such code yourself? If you are using Spring already, use the JdbcTemplate instead. It can be initialized with your DataSource and will manage all that for you.
You are requiring a connection from the pool but you never closes it (same for the statement actually). Using JdbcTemplate prevents you from having those issues in the first place.
Something like
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(...)
See the javadoc for more details.

insert into table using hibernate #Transactional

I am using #Transactional annotation to test inserting some data into one of the tables through a Spring application. My test succeeds, but I do not see any data being inserted into the table.
Here are the relevant code snippets:
MyTest:
#TransactionConfiguration(transactionManager="MyTxManager")
#Transactional
public class MyTest {
#Autowired
private DataProvider provider;
#Test
#Transactional
void testInsert() {
Order purchaseOrder = new Order("ID1", "LER", "VDR1", 0, );
provider.addRow(purchaseOrder);
}
}
DataProvider:
public class DataProvider extends DatabaseProvider {
// some stuff...
#Transactional
public void insertRow(Order purchaseOrder) {
/*
* SessionFactory is got through autowiring
* and is working perfectly fine.
*/
Session session = sessionFactory.getCurrentSession();
// This should save the row into the table - which it doesn't :(
session.save(purchaseOrder);
}
}
information-providers.xml
<bean id="DataProvider" class="com.util.DataProvider">
<property name="sessionFactory" ref="MySessionFactory" />
</bean>
hibernate.xml containing the configuration of session factory
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
parent="AbstractSessionFactory" depends-on="EnvironmentHelper">
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.connection.provider_class">com.hibernate.ConnectionPool</prop>
<prop key="hibernate.connection.driver_class">${driverClassName}</prop>
<prop key="hibernate.connection.url">${databaseURL}</prop>
<prop key="hibernate.connection.username">${databaseUsername}</prop>
<prop key="hibernate.connection.password">${databasePassword}</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.default_schema">${databaseDefaultSchema}</prop>
</props>
</property>
</bean>
<!-- Use Spring transactions for Hibernate -->
<tx:annotation-driven transaction-manager="MyTxManager" mode='proxy' proxy-target-class='true'/>
<bean id="MyTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="MySessionFactory" />
</bean>
</beans>
I think the problem in rolling back the transactions. See here defaultRollback method.
Try like this:
#TransactionConfiguration(transactionManager="MyTxManager", defaultRollback=false)
Your problem is that MyProvider myProviderInstance = new MyProvider(); the myProviderInstance isn't maintained by Spring container, you just new it, so the Spring can't do anything about it, definitely the transaction doesn't work. You should config the bean in Spring applicationcontext.xml and load it with ApplicationtContext, you can find dozens of sample after google it. And since you use Mysql you should make sure that you use innerDB mode or the transaction isn't supported by mysql.
add the line <tx:annotation-driven/> to your spring configuration

Hibernate list using cache? -Not updating entity attribute

I have an application that uses hibernate.
I did the following:
Used List to list some entities on database
Logged in my Mysql Database manualy and updated a field in some
entities
Used List again in hibernate doing an identical query as 1
The entity that hibernate listed was not updated.
If I close and open the application. it then shows the entity updated correctly.
Is hibernate using some kind of cache by default?
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/XXX</property>
<property name="hibernate.connection.username">XXXXXXXXXX</property>
<property name="hibernate.connection.password">XXXXXXXXXX</property>
<property name="show_sql">true</property>
Code that lists the entity:
Session s = HibernateUtil.getSession();
Criteria c = s.createCriteria(Solicitacao.class, "s");
//Add some Restrictions here
List<Solicitacao> ls = c.list();
s.close();
My Session factory:
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
static {
// Configurações iniciais de caminho dos diretórios e arquivos
URL url = HibernateUtil.class.getProtectionDomain().getCodeSource().getLocation();
File myFile = null;
try {
myFile = new File(url.toURI());
} catch (Exception ex) {
}
File dir = myFile.getParentFile();
File xml = new File(dir, "hibernate.cfg.xml");
/*
* sessionFactory = new AnnotationConfiguration() .configure("br/com/netradiobrasil/pcp/" +
* "hibernate/hibernate.cfg.xml") .buildSessionFactory();
*/
sessionFactory = new AnnotationConfiguration().configure(xml).buildSessionFactory();
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
I tryed to add those lines in my hibernate.cfg.xml
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
Also tryed to use: session.setCacheMode(CacheMode.IGNORE)
but still didnt solve my problem
Let me guess
After executing this
Session s = HibernateUtil.getSession();
Criteria c = s.createCriteria(Solicitacao.class, "s");
//Add some Restrictions here
List<Solicitacao> ls = c.list();
You changed entries in database manually and then reran the query ? If yes then can you close the session and then rerun your code ?
Adding those lines in my hibernate.cfg.xml - that enables c3p0 fixed my problem
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">40</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">100</property>