How to get jdbc connection from hibernate session? [duplicate] - java

This question already has answers here:
session.connection() deprecated on Hibernate?
(13 answers)
Closed 9 years ago.
I want to get jdbc connection from hibernate session.There is method inside hibernate session
i.e session.connection(); but it has been deprecated. i know this works still but i dont want to use deprecated method as i am sure they must have provide some alternative for this?
At http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Session.html connection method api says using org.hibernate.jdbc.Work for this purpose but i dont find any example for that?

Here is how you can use it:
session.doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {
//connection, finally!
}
});

Try this:
((SessionImpl)getSession()).connection()

I had a similar Problem and I used the ConnectionProvider class to get the connection. See my solution:
Session session = entityManager.unwrap(Session.class);
SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session.getSessionFactory();
ConnectionProvider connectionProvider = sessionFactoryImplementation.getConnectionProvider();
try {
connection = connectionProvider.getConnection();
...
}

Related

StatelessSession#connection() deprecated on Hibernate?

I'm cleaning up some warnings, and I came up on some code using the connection() method of StatelessSession, whose deprecation doc says they missed it when deprecation the same method on Session.
Now, the answers to this question point to the doWork method on Session, but no such method exists on StatelessSession. So, how is one supposed to fix this deprecation?
The StatelessSession.connection() method goal was to:
Return the current JDBC connection associated with this instance.
The StatelessSession inherits this method from SessionImplementor, which is not deprecated, so it's safe to use it. Even if it's going to be removed from StatelessSession, you will still have this method from the SessionImplementor.
You can do something like this:
StatelessSession statelessSession = HibernateUtil.getSessionFactory().openStatelessSession();
try {
((StatelessSessionImpl) statelessSession).getJdbcConnectionAccess().obtainConnection().setTransactionIsolation(TRANSACTION_REPEATABLE_READ);
} catch (SQLException e) {
e.printStackTrace();
}

($Proxy6) org.postgresql.jdbc4.Jdbc4Connection#5894585b, what does it mean?

I am trying to downcast java.sql.Connection to org.postgresql.jdbc4.Jdbc4Connection like this:
As you can see, Netbeans tells me localConn is ($Proxy6) org.postgresql.jdbc4.Jdbc4Connection#5894585b, and it is not an instance of org.postgresql.jdbc4.Jdbc4Connection.
So here are my questions:
What does ($Proxy6) org.postgresql.jdbc4.Jdbc4Connection#5894585b mean?
How can I get org.postgresql.jdbc4.Jdbc4Connection from it?
Thanks,
Update Information:
localConn instanceof org.postgresql.jdbc4.Jdbc4Connection returns false.
update
I use Mybatis.
I suppose that you are using iBatis/MyBatis. If so, there is a static method on com.ibatis.common.jdbc.SimpleDataSource that returns the unwrapped connection:
public static Connection unwrapConnection(Connection conn)
This method will return the real connection without the proxy, and you will can do the downcast.
A Proxy class is a class that wraps an existing Interface and lets you intercept calls
made to the object.
This causes a problem in that the proxy will only recognise that it is of that interface
type. Which in this case is most likely to be javax.sql.Connection.
you could try this
Connection conn = localConn.createStatement().getConnection();

Find statements related to a Connection

I am developing on a big application which uses a Connection Pool and has lots of classes using its connections.
Recently we had some issues because some classes were not closing the statements before invoking the connection.close() method, wrongly believing that when the connection is closed any related statement is also closed.
At the moment I am refactoring some code and developing an abstract class which will manage the connections (get them from and put them back into datasource) and leave the statement details to be implemented into subclasses.
In order to avoid future errors related to statements not being closed, I thought about implementing some check before returing the conneciton into the Pool and if I find some opened statements either close them or log a Warning.
The resulting class would look like this:
public abstract class AbstractDatabaseLoader {
private DataSource dataSource;
public final DatabaseValues load(DatabaseParams params) {
DatabaseValues result = null;
Connection connection = null;
try {
connection = dataSource.getConnection();
result = load(connection, params);
} catch (Exception ex) {
// some logging;
} finally {
if (connection != null) {
try {
if (validateStatements(connection)){
logger.warn("The Connection is being returned into the POOL with opened Statments!");
}
connection.close();
} catch (SQLException e) {
// some logging.
}
}
}
return result;
}
protected abstract DatabaseValues load(Connection connection, DatabaseParams params);
private boolean validateStatements(Connection connection){
// Do Something here to validate if statements were properly closed.
}
}
However, I found no way to recover the statements from the connection interface.
So:
Is this even possible without having to depend on specific implementations?
Would you recommend this approach?
Many thanks,
Carles
Connection.close API says
Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released.
if it is even a Connection Pool where the connection is not actually closed, it is the Connection Pool provider duty to close all Statements and ResultSets created by this Connection, and this is what good providers do in practice, see commons-dbcp http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/DelegatingConnection.html#close() it says Closes the underlying connection, and close any Statements that were not explicitly closed.

Should the "connection" argument of doWork() be closed?

I am using a C3P0 Connection Pool with Hibernate to execute some JDBC operations. However, I am getting a "Closed Connection" (SQL Error: 17008, SQLState: null) error after some time of usage.
I am using the org.hibernate.jdbc.Work interface to perform my operations:
public class ClassThatDoesWork implements Work {
#Override
public void execute(final Connection connection)
throws SQLException {
doSomeWork();
//should connection be closed here?
}
}
My question is: should the connection object passed as an argument to the execute() method be closed at the end of that method or Hibernate takes care for that automatically?
EDIT
These are the Hibernate and c3p0 parameters used:
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.pool_size=10
hibernate.dialect=org.hibernate.dialect.Oracle9iDialect
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider
hibernate.show_sql=false
acquireIncrement=3
acquireRetryDelay=500
acquireRetryAttempts=5
breakAfterAcquireFailure=false
checkoutTimeout=0
connectionTesterClassName=com.mchange.v2.impl.DefaultConnectionTester
debugUnreturnedConnectionStackTraces=false
dataSourceName=irrelevantDB
identityToken=irrelevantDB
idleConnectionTestPeriod=0
initialPoolSize=3
maxConnectionAge=0
maxIdleTime=7200
maxIdleTimeExcessConnections=0
maxPoolSize=20
maxStatements=50
maxStatementsPerConnection=0
minPoolSize=5
numHelperThreads=3
propertyCycle=0
testConnectionOnCheckin=false
testConnectionOnCheckout=true
unreturnedConnectionTimeout=0
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=10
hibernate.c3p0.max_statements=50
The database connection is passed in as a method argument by Hibernate, and thus should not be tampered with (e.g. closed) inside the method -- this is Hibernate's responsibility.

Java: connecting to db to fetch data

I have a question regarding Java when fetching data from, lets say MySQL database. As of now I need to write quite a lot of redundant code when fetching data. And I wonder if there is a better way to do that.
E.g. I have an method which fetch data from a table A. The method for that will look something like this then
public void readDataBase() throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
statement = connect.createStatement();
resultSet = statement
.executeQuery("select * from FEEDBACK.COMMENTS");
writeResultSet(resultSet);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
I wonder if there's a better way to write a method such as this one. Because it gets quite ugly when you have to write code such as this, namely that you have to write those line to getConnection all the time in every method that fetch data from the database.
Use Spring, with MyBatis or spring-jdbc for data access instead of raw JDBC.
spring-jdbc is a library wrapping basic JDBC code where you can provide callbacks to specify how you want resultsets mapped to objects and such. Mybatis is a little higher-level, you specify your queries in an xml file.
With Spring the big win is you get declarative transactions so you have no code starting and committing transactions, you also get templates for data access objects, and setting up a connection pool is easy. And there are plenty of examples for how to put the pieces together.
At some point you're better off writing your own DAO which handles all the plumbing for you.
I would do different things depending on whether I am in a single threaded batch job or inside a container.
For single threaded batch job:
create just one connection and reuse it
create just one prepared statement and reuse it
optimize commit calls
For J2EE
use the container managed data source pool
Most of the times when you write a program working with a database you do not open a connection every time you want to do something with it. Instead you open a connection at the beggining of the program and then use it every time when accessing a database.
Take a look at this example (pseudocode!):
class Database {
private Connection conn;
public Database() {
connect();
}
private void connect() {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbUrl);
}
public void close() {
conn.close();
}
private ResultSet readSth() {
statement = conn.createStatement();
return statement.executeQuery("select * from FEEDBACK.COMMENTS");
}
private void doSth() {
// do sth else with conn
}
}
You can create a class having static method there, that returns you an instance of connection like below:
import java.sql.*;
import java.util.Properties;
public class Getconnection{
private static final String dbClassName = "com.mysql.jdbc.Driver";
private static final String CONNECTION ="jdbc:mysql://127.0.0.1/dbUserData";
private static Properties p = new Properties();
public static Connection getConnection(){
p.put("user","root");
p.put("password","library");
try{
Class.forName(dbClassName);
Connection con=DriverManager.getConnection(CONNECTION,p);
return con;
}
catch(Exception ie){
ie.printStackTrace();
return null;
}
}
}
So that you do not need to create different instances of connection, and change only at one place if you want to...
I think you are suffering from basic code organization. For example, you should only create the connection once and then pass it around to whatever methods need it. Typically, people use connection pools so that only a certain number of connections ever exist to the db (because they are expensive) and a connection pool manager will loan them out as needed and keep track of their states. There are a few connection pool libraries in Java (Apache has one) but I have had good luck using: http://sourceforge.net/projects/c3p0/
I dont really like heavy ORMs such as Hibernate but I do I like MyBatis. It lets me wright SQL and doesnt inject itself all over my domain models: http://www.mybatis.org/java.html I think you would benefit greatly by having a Data Access Object layer (DAO). This layer abstracts out communication with your data so the layers above can just fetch collections of data without worrying about the underlying SQL it took to generate that list.
I've moved away from direct JDBC access since I started using ORM (eg. Hibernate).
Or why dont you have some publicly available static method to read from the db:
public ResultSet readDataBase(String query) throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
statement = connect.createStatement();
return statement.executeQuery(query);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
and you can have similar methods when you do update/delete, etc

Categories

Resources