Hibernate: установить время ожидания запроса по умолчанию? - PullRequest
11 голосов
/ 20 января 2010

Я делаю несколько больших запросов к своей базе данных с помощью Hibernate, и иногда у меня возникают тайм-ауты. Я хотел бы избежать установки тайм-аута вручную для каждого Query или Criteria.

Есть ли какое-либо свойство, которое я могу дать моему AnnotationConfiguration, которое установило бы приемлемое значение по умолчанию для всех выполняемых мной запросов?

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

Ответы [ 4 ]

9 голосов
/ 20 января 2010

JPA 2 определяет подсказку javax.persistence.query.timeout для указания времени ожидания по умолчанию в миллисекундах. Hibernate 3.5 (в настоящее время все еще в бета-версии) будет поддерживать эту подсказку.

См. Также https://hibernate.atlassian.net/browse/HHH-4662

4 голосов
/ 15 мая 2012

JDBC имеет этот механизм с именем Query Timeout, вы можете вызвать метод setQueryTime объекта java.sql.Statement, чтобы включить этот параметр.

Hibernate не может сделать это унифицированно.

Если ваше приложение восстановит соединение JDBC vi java.sql.DataSource, вопрос может быть легко решен.

мы можем создать DateSourceWrapper для соединения с прокси, который выполняет setQueryTimeout для каждого созданного им оператора.

Пример кода легко читается, для этого я использую некоторые классы утилит Spring.

public class QueryTimeoutConfiguredDataSource extends DelegatingDataSource {

private int queryTimeout;

public QueryTimeoutConfiguredDataSource(DataSource dataSource) {
    super(dataSource);
}

// override this method to proxy created connection
@Override
public Connection getConnection() throws SQLException {
    return proxyWithQueryTimeout(super.getConnection());
}

// override this method to proxy created connection
@Override
public Connection getConnection(String username, String password) throws SQLException {
    return proxyWithQueryTimeout(super.getConnection(username, password));
}

private Connection proxyWithQueryTimeout(final Connection connection) {
    return proxy(connection, new InvocationHandler() {
        //All the Statement instances are created here, we can do something
        //If the return is instance of Statement object, we set query timeout to it
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object object = method.invoke(connection, args);
            if (object instanceof Statement) {
                ((Statement) object).setQueryTimeout(queryTimeout);
            }
            return object;
        });
}

private Connection proxy(Connection connection, InvocationHandler invocationHandler) {
    return (Connection) Proxy.newProxyInstance(
            connection.getClass().getClassLoader(), 
            ClassUtils.getAllInterfaces(connection), 
            invocationHandler);
}

public void setQueryTimeout(int queryTimeout) {
    this.queryTimeout = queryTimeout;
}

}

Теперь мы можем использовать этот QueryTimeoutConfiguredDataSource, чтобы обернуть ваш существующий источник данных, чтобы прозрачно установить время ожидания запроса для каждого оператора!

Файл конфигурации Spring:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource">
        <bean class="com.stackoverflow.QueryTimeoutConfiguredDataSource">
            <constructor-arg ref="dataSource"/>
            <property name="queryTimeout" value="1" />
        </bean>
    </property>
</bean>
1 голос
/ 20 января 2010

Вот несколько способов:

  • Использование метода фабрики или базового класса для создания всех запросов и установки времени ожидания перед возвратом объекта Query
  • Создание собственной версии org.hibernate.loader.Loader и установите время ожидания в doQuery
  • . Используйте AOP, например Spring, чтобы вернуть прокси для Session;добавить совет, который оборачивает метод createQuery и устанавливает время ожидания для объекта Query перед его возвратом
0 голосов
/ 20 марта 2016

Для установки глобальных значений времени ожидания на уровне запроса - добавьте приведенное ниже в файл конфигурации.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
    <property name="queryTimeout" value="60"></property>
</bean>

Для установки значений глобального тайм-аута на уровне транзакции (INSERT / UPDATE) - добавьте приведенное ниже в файл конфигурации.

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
    <property name="dataSource" ref="dataSource" />
    <property name="defaultTimeout" value="60" />
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    </property>
</bean>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...