A few days ago my website crashed and showed me this error:
java.lang.NoClassDefFoundError: Could
not initialize class
com.omicc.hibernate.util.HibernateUtil
So I asked the hosting company about any changes that they may have made. They fixed the problem and told me to use JDBC connections instead of socket connections.
I am using hibernate and c3p0 with MySQL and as far as I know they use JDBC connections.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
So do any of you guys know what he was talking about? :D (and yes he is not answering now!)
EDITED>>>>
Solved!, so here is what i did
i upgraded my hibernate from hibernate from 3.5.0 to 3.6.1
and new hibernate required hibernate-jpa-2.0-api-1.0.0.Final.jar and slf4j-simple1.6.1 .
and problem solved.
i think that the hosting company updated their hibernate.jar and it caused some reference problems.
Rewrite your HibernateUtil so it doesn't instantiate in a static block. Instead make it a singleton with a synchronized getInstance. Then
private static SessionFactory cache;
synchronized SessionFactory getInstance() throws SQLException {
if (cache != null) return cache;
// try/catch and rethrow SQLException
try {
Class.forName("com.mysql.jdbc");
} Exception (e) {
throw new SQLException(e);
}
// Test connection with JDBC
// Create a non connection pooled raw connection, try/finally close it
// throw SQL Exception if it fails
testMe()
// finally create the sessionFactory
.... build your Configuration object
.... then
try {
SessionFactory me = ....buildSessionFactory
} catch (RuntimeException e) {
throw new SQLException(e);
}
cache = me;
return cache;
}
Some comments: some people will prefer an unchecked exception, which is fine.
The reason I like doing the raw connection once is that on startup it tends to bollix up connection pool/hibernate less if the SQL Server happens to be done. Once they initialize successfully I've not had recovery issues. But that's a personal taste thing, and you could skip testMe() as well.
Point is this way you will SEE the Exception occurring, and I predict to you it will clearly implicate the connection to the hosting company :)
Related
So,
The hibernate SessionFactory is available.
Now, on java.sql.Connection there is a method connection.setTransactionIsolation.
Now, from sessionFactory you can openSession(), or getCurrentSession()
From there, we can do:
session.doWork(connection -> { ... connection.setTransactionIsolation ... } )
However, my memory tells me this is already too late.
One actually needs to do connection.setTransactionIsolation likely before the Session has even been created.
Is this not true?
Further, setReadOnly has the same requirements.
Now, to get the connection before the session is created there is this answer:
https://stackoverflow.com/a/29844998/961018
But that requires the datasource.
So is there anyway one, can get the datasource from SessionFactory, so I can create this logic from what I currently have?
EDIT
RESPECTFULLY, DO NOT UTTER THE WORDS S.P.R.I.N.G or A.N.N.O.T.A.T.I.O.N.S.
The "Transaction Isolation" property has got a "Connection" level, that's why you have to apply it once creating the connection and not at transaction level or (like general rule for all connection) on SessionFactory.
Considering what you are trying to do, you have actually two different options to set the transaction isolation.
The most used, clean and recommended one is by setting the specific hibernate property, like following one:
<property name="hibernate.connection.isolation">2</property>
On the specific case, value 2 correspond "READ COMMITTED".
Otherwise, you could try to get the connection instance from the Session, like following code:
Session session = sessionFactory.getSession();
try {
session.connection().setTransactionIsolation(2);
} catch (HibernateException | SQLException e) {
e.printStackTrace();
}
Please bear in mind that the above is quite a dirty way to do that and it's not guarantee that it works. Moreover the method connection() of org.hibernate.Session is deprecated, so you should not use it.
However, I personally used for some unit tests (as an experiment) and it worked fine.
I want to create oracle connection. Currently i am passing jdbc connection to create struct descriptor and here i am getting exception as below. so to avoid this, required to create a java.sql.connection or oracle connection instead of getting from data source.
org.jboss.resource.adapter.jdbc.jdk8.WrappedConnectionJDK8 cannot be cast to oracle.jdbc.OracleConnection
I found for JDK6 a solution, but it does not work for JDK8
How to create oracle connection in Spring application deployed in JBoss Server? (WrappedConnectionJDK6 cannot be cast to oracle.jdbc.OracleConnection)
You should use the unwrap method to obtain your instancedatasource.getConnection().unwrap(OracleConnection.class)
if you use an application server you can configure a Datasource and then use simple code like:
public class JDBCConnection {
#Resource(name = "jdbc/betting-offer-db") private DataSource dataSource;
public void executeQuery() {
logger.info("Reloading {}", getCacheNames());
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(getQuery())) {
processStatement(stmt);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
I have a web application that currently uses c3p0 and Hibernate to connect to a Firebird 1.5 database.
I am facing a problem from time to time where the database just stops responding, even trying to manually restart the service doesn't have any effect, and it doesn't generate any logs, so I have to manually reboot the machine to get it working again.
I think that maybe Firebird hangs when the pool tries to acquire a specific number of connections or something like that. So, I need to test my app without connection pooling, to check if this is or is not the problem.
I can't simply remove c3p0 configs from persistence because this way Hibernate would use its own integrated connection pool. So how to do it?
The most flexible solution is to use an explicit DataSource, instead of configuring the connection pooling through Hibernate. One option to configure a non-pooling DataSource is by using DriverManagerDataSource:
#Override
protected Properties getProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
//log settings
properties.put("hibernate.hbm2ddl.auto", "update");
//data source settings
properties.put("hibernate.connection.datasource", newDataSource());
return properties;
}
protected ProxyDataSource newDataSource() {
DriverManagerDataSource actualDataSource = new DriverManagerDataSource();
actualDataSource.setUrl("jdbc:hsqldb:mem:test");
actualDataSource.setUsername("sa");
actualDataSource.setPassword("");
ProxyDataSource proxyDataSource = new ProxyDataSource();
proxyDataSource.setDataSource(actualDataSource);
proxyDataSource.setListener(new SLF4JQueryLoggingListener());
return proxyDataSource;
}
This way you can choose a pooling or a non-pooling DataSource.
To get a better understanding of you connection pooling resources usage, you can configure FlexyPool to collect metrics for:
concurrent connections
concurrent connection requests
data source connection acquiring time
connection lease time
maximum pool size
total connection acquiring time
overflow pool size
retries attempts
I found documentation for hibernate 3.3 and 4.3 that says:
Just replace the hibernate.connection.pool_size property with
connection pool specific settings. This will turn off Hibernate's
internal pool.
Hibernate will use its org.hibernate.connection.C3P0ConnectionProvider
for connection pooling if you set hibernate.c3p0.* properties
So remove hibernate.connection.pool_size and any hibernate.c3p0... properties from configuration, than connection pooling is disabled.
Adding to Vlad's answer:
If somebody still faces this:
Be sure to remove "hibernate-c3p0" from your classpath, if exists, since this will automatically enable MChange c3p0 connection pool.
Another option that, you can close the connection manually when closing the entity manager:
....
SessionImpl ses = (SessionImpl) session;
close(ses.connection());
try {
session.close();
} catch (Exception e) {
logger.error(e);
}
........
Note: the above manual closing will work with the default pool of hibernate, not hibernate default one.
Good Luck
I am wondering what would be a reasonable number for my connection.pool_size? to what aspects is it related? Also need to know how to test the application once a size is defined for it.
My application is going to be used by AT LEAST 100 users concurrently, it has more than 20 tables in its database. My database is MySQL and AT LEAST 12 systems are using my application at the same time. Please let me know if you need to know more.
I have also found the following which helps to define the connection pool size but still not sure what the reasonable number is.
Hibernate's own connection pooling algorithm is, however, quite rudimentary.
It is intended to help you get started and is not intended for use in a production
system, or even for performance testing. You should use a third party pool for
best performance and stability. Just replace the hibernate.connection.pool_size
property with connection pool specific settings. This will turn off Hibernate's
internal pool. For example, you might like to use c3p0.
connection.pool_size indicates the maximum number of pooled connections. So it is
better to keep it at a logical count. It depends on your application and DB how
much it can handle. 10 is a reasonable count that will typically used as it is
sufficient for most cases.
My hibernateUtil is as following
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal();
private static SessionFactory sessionFactory;
private static SessionFactory configureSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new
ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry( );
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
} catch (HibernateException e) {
System.out.append("** Exception in SessionFactory **");
e.printStackTrace();
}
return sessionFactory;
}
static {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateUtil() {
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
}
you must test it with your actual framework how much minimum and maximum connection pool you will use. according to this article :
Small Connection pool :
Will have faster access on the connection table.
But may not have enough connections to satisfy requests and requests
may spend more time in the queue.
Large Connection pool:
Will have more connections to fulfill requests
and requests will spend less (or no) time in the queue at the cost of
slower access on the connection table.
so you must test with some connection pool, do some load testing. Also consider getting performance/resource usage information on the current load, and doing some transaction cost based analysis.
And by the result of the analysis, if the access to the connection table are too slow then you can decrease the connection pool, or if the connection is not enough you can add more connection pool. Balance those factor to get optimal time lapse.
If you are using some application server (Jboss, Weblogic, Glassfish, etc...), this guy can show you some statistics on your pool usage. Analise some of this data (max queue time, max connections in use, etc) and run some tests to find what numbers fit your case best.
You have to use third party connection pool like c3p0. 20 to 30 connctions required for 100 concurrecnt user. You have to do the perfomance testing using some tool(like jmeter). Using perfomance tool you can send the n number of concurrecnt request. based on that report you may increse or decrese the connections size.
The only reasonable way to know how many connections you need is by doing monitoring and adjustments. That's because the relation between the connection acquisition time, the pool size, and the incoming request throughput is given by Little's Law, therefore the pool size depends on how many request are coming and how long are you willing to wait prior to obtaining a connection.
FlexyPool is an open source framework that allows you to monitor connection usage, and it can even increase the pool size beyond the initial capacity.
FlexyPool collects the following metrics:
concurrent connections histogram
concurrent connection requests histogram
data source connection acquiring time histogram
connection lease time histogram
maximum pool size histogram
total connection acquiring time histogram
overflow pool size histogram
retry attempt histogram
It supports almost all major connection pooling solutions:
Apache DBCP
Apache DBCP2
C3P0
BoneCP
HikariCP
Tomcat CP
Vibur DBCP
Bitronix Transaction Manager
Atomikos TransactionsEssentials
Java EE DataSources
It uses Codahale/Dropwizard Metrics so you can integrate it with Graphana or Graphite.
So, back to your question. You can start with a small pool size (5 connections) and configure an overflow buffer of 5 extra connections. You can set up the timeout interval according to your application SLA (100 ms). Then, you can monitor the connection pool usage as explained in this article.
This post is intended to be less of a question and more a confirmation that I'm doing things correctly. I've seen many similar posts but I'm not sure I fully understand everything that's been said.
The problem is that, after a certain amount of time, I get an exception when trying to establish a connection to my oracle database. (I'm using Tomcat 6.0 and Spring)
Previously I had the following configuration:
private PoolDataSource poolDataSource = null;
public MainDAOImpl(String url, String username, String password)
throws Exception
{
poolDataSource = PoolDataSourceFactory.getPoolDataSource();
try
{
poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
poolDataSource.setURL(url);
poolDataSource.setUser(username);
poolDataSource.setPassword(password);
}
catch( SQLException e )
{
...
}
}
public List<Object> getValues(String query)
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = poolDataSource.getConnection();
preparedStatement = connection.prepareStatement(query);
...
}
catch( SQLException e )
{
...
}
finally
{
//close connections
}
}
However, sometimes the preparedStatement = connection.prepareStatement(query); threw an SQLException with a "Closed Exception" message.
It's important to note that the MainDAOImpl's constructor gets called only once per server restart (it's dependency injected via Spring).
I've recently changed my setup like so:
private DataSource dataSource = null;
public MainDAOImpl()
throws Exception
{
try
{
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/myOracleConn");
}
catch( NamingException e )
{
...
}
}
and poolDataSource.getConnection() to dataSource.getConnection().
I've also added the following Resource to my Context in Tomcat:
<Resource name="jdbc/myOracleConn" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="<myURL>"
username="<myUsername>" password="<myPassword>"
maxActive="20" maxIdle="10" maxWaith="-1" />
This basically follows http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html word-for-word.
Everything seems to be working. My question is, will these changes solve my closed connection problem or is there something different I need to do?
Thanks,
B.J.
First of all, if you are using Spring for dependency injection, I would recommend that you also use DI to inject the DAO's dependencies into it.
In other words, your DAO should have a DataSource injected into it, rather than the DAO implementation knowing either 1) what type of DataSource to construct or 2) how and where to look it up in JNDI. Spring can handle JNDI lookups for you.
I'd also recommend using Spring's JdbcTemplate, as it makes for a great wrapper over raw JDBC calls yourself.
Finally, the actual exception you are getting may just be because the database server is closing long-open connections. Not sure which connection pool implementation you are using, but in commons-dbcp there is an option for a "validationQuery" which the pool will execute before returning a connection to verify the connection is still valid. I'm sure most other pools supply similar features, which I would recommend here - this way your DAO is never receiving stale connections from the pool.