Если использование Hibernate с базой данных (и c3p0 dbpooling) все еще возможно и безопасно, напрямую получить соединение в обход Hibernate - PullRequest
0 голосов
/ 08 октября 2019

Использование Hibernate 4.3.11 с H2 1.4.199 и C3p0

Если использование Hibernate с базой данных все еще возможно и безопасно, чтобы напрямую получить соединение из пула в обход Hibernate?

Я пытаюсьнаписать SQL-запрос, теперь я знаю, что могу использовать session.createSQLQuery (), но это возвращает класс SQLQuery org.hibernate Hibernate, а не java.sql.Connection, и это вызывает проблему для меня, пытаясь установить параметры, поэтому яхотел попробовать использовать соединение вместо.

1 Ответ

1 голос
/ 08 октября 2019

Попробуйте это.

import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;

sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(ConnectionProvider.class).getConnection();

Я не проверял это и не могу сделать это в настоящее время. Я только 50-50 на ConnectionProvider, так как я не уверен, что класс провайдера для c3p0. Может быть org.hibernate.c3p0.internal.C3P0ConnectionProvider или вы уже знаете это.

РЕДАКТИРОВАТЬ 11-10-2019

Соединения возвращаются из реализаций интерфейса org.hibernate.engine.jdbc.connections.spi.ConnectionProvider, насколько это возможно. как я вижу.

org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl

Обе эти реализации извлекают java.sql.Connection из Datasource или PooledConnections, которые внутренне поддерживаются во время регистрации службы.

DatasourceConnectionProviderImpl имеет следующие методы.

    @Override
    public Connection getConnection() throws SQLException {
        if ( !available ) {
            throw new HibernateException( "Provider is closed!" );
        }
        return useCredentials ? dataSource.getConnection( user, pass ) : dataSource.getConnection();
    }

    @Override
    public void closeConnection(Connection connection) throws SQLException {
        connection.close();
    }

DriverManagerConnectionProviderImpl методы следуют

@Override
public Connection getConnection() throws SQLException {
    if ( !active ) {
        throw new HibernateException( "Connection pool is no longer active" );
    }

    return pool.poll();
}

public Connection poll() throws SQLException {
        Connection conn = availableConnections.poll();
        if ( conn == null ) {
            synchronized (allConnections) {
                if(allConnections.size() < maxSize) {
                    addConnections( 1 );
                    return poll();
                }
            }
            throw new HibernateException( "The internal connection pool has reached its maximum size and no connection is currently available!" );
        }
        conn.setAutoCommit( autoCommit );
        return conn;
    }


@Override
public void closeConnection(Connection conn) throws SQLException {
    if (conn == null) {
        return;
    }

    pool.add( conn );
}

И, как вы можете видеть, оба они имеют разные способы обработкисоединения. Я не представляю серьезных проблем, если вы закроете соединение, так как первое возвращает новое соединение, а второе пополняет пул, если соединение закрыто. Однако, если вы не собираетесь закрываться, узнайте, какая реализация вызывается в вашем приложении, и убедитесь, что у вас нет утечки.

Две другие реализации предназначены для режимов Hikari и UserSupplied.

...