How do I fetch a JDBC connection in a hibernate 4.3 Integrator?
Asked Answered
M

3

6

When implementing an org.hibernate.integrator.spi.Integrator for hibernate 4.3, one gets a Configuration, SessionFactoryImplementor and SessionFactoryServiceRegistry object.

One way to fetch the metadata is to obtain a connection provider: sessionFactory.getJdbcServices().getConnectionProvider()

But getConnectionProvider() is deprecated and does not work for a multi tenant setup.

Javadocs say

Access to connections via org.hibernate.engine.jdbc.spi.JdbcConnectionAccess should be preferred over access via ConnectionProvider, whenever possible.

But my problem is, that I don't find a way to obtain a JdbcConnectionAccess. It would be possible to use the given SessionFactoryServiceRegistry and replicate the code from SessionFactoryImpl#buildLocalConnectionAccess(), but that is not a nice solution.

What is the recommended way to fetch a connection in an Integrator?

Mcdevitt answered 28/11, 2014 at 23:29 Comment(2)
Did you find a solution for this problem?Drily
No, I didn't find a solution until now.Mcdevitt
D
1

I had a similar problem with deprecated method "sessionFactory.getJdbcServices().getConnectionProvider()". I used this function to get the dataSource for my FlywayIntegrator. I used them like in this example: http://blog.essential-bytes.de/flyway-hibernate-und-jpa-integrieren

Without the getConnectionProvider() i didn't found a solution to get the needed properties to connect with my database.

As a workaround i putted these properties in the standalone.xml file of my jboss configuration like this:

<system-properties>
    <property name="com.mycomp.myapp.servername" value="localhost"/>
    <property name="com.mycomp.myapp.databasename" value="xxx"/>
    <property name="com.mycomp.myapp.databaseuser" value="yyy"/>
    <property name="com.mycomp.myapp.databasepassword" value="zzz"/>
</system-properties>

In my flyway integrator i can now read these properties by:

private DataSource getDataSourceFromSystemProperty() {
    String servername = System.getProperty("com.mycomp.myapp.servername");
    if (servername == null || servername.isEmpty()) {
        logger.warning("No system property found in standalone.xml file for com.mycomp.myapp.servername");
        servername = "localhost";
    }
    String databaseName = System.getProperty("com.mycomp.myapp.databasename");
    if (databaseName == null || databaseName.isEmpty()) {
        logger.warning("No system property found in standalone.xml file for com.mycomp.myapp.databasename");
        databaseName = "xxx";
    }
    String databaseUser = System.getProperty("com.mycomp.myapp.databaseuser");
    if (databaseUser == null || databaseUser.isEmpty()) {
        logger.warning("No system property found in standalone.xml file for com.mycomp.myapp.databaseuser");
        databaseUser = "yyy";
    }
    String databasePassword = System.getProperty("com.mycomp.myapp.databasepassword");
    if (databasePassword == null || databasePassword.isEmpty()) {
        logger.warning("No system property found in standalone.xml file for com.mycomp.myapp.databasepassword");
        databasePassword = "zzz";
    }

    final PGSimpleDataSource dataSource = new PGSimpleDataSource();
    dataSource.setServerName(servername);
    dataSource.setPortNumber(5432);
    dataSource.setDatabaseName(databaseName);
    dataSource.setUser(databaseUser);
    dataSource.setPassword(databasePassword);
    return dataSource;
}

Maybe this helps...

Drily answered 27/1, 2015 at 11:50 Comment(1)
Thanks for your effort, but I need the Connection to obtain metadata about the connection (e. g. API level). Therefore configuring the details is no option.Mcdevitt
S
1

Getting connection in Integrator.integrate() method in Hibernate 5 could be done by:

final DataSource ds = (DataSource) sessionFactory.getProperties().get("hibernate.connection.datasource");
final Connection conn = ds.getConnection();
Shilling answered 15/6, 2017 at 12:35 Comment(1)
This was working fine and the most simple solution, without providing any extra parameters (like Gatschet's solutiuon). Thanks.Tarsia
K
0

You could do the following from your Integrator implementation:

SessionImplementor sessionImplementor = (SessionImplementor) sessionFactory.getCurrentSession();
Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();

The sessionFactory here is the SessionFactoryImplementor you receive from your implemented methods.

Kiley answered 10/12, 2014 at 21:30 Comment(3)
In the integrator there is no current session so a HibernateException with the message No CurrentSessionContext configured! is thrown.Mcdevitt
Oups... Do you use the HibernateUtil pattern? Would it work if you use sessionFactory.openSession() instead, either from the session factory obtained in the method parameter, of from your HibernateUtil.getSessionFactory() ?Auden
No, I don't us the HibernateUtil pattern. I use hibernate in a JPA environment and use a library to extend the supported basic types. The library integrates into hibernate implementing an Integrator. But at runtime it is not possible to fetch a SessionImplementor using sessionFactory.openTemporarySession().Mcdevitt

© 2022 - 2024 — McMap. All rights reserved.