Hibernate:设置默认查询超时?

mal*_*ere 12 java configuration hibernate timeout jpa

我正在使用Hibernate对我的数据库进行一些大查询,我有时会遇到超时.我想避免在每个Query或者手动设置超时Criteria.

我可以给我的任何属性是否Query会为我运行的所有查询设置一个可接受的默认值?

如果没有,我如何在Hibernate查询上设置默认超时值?

Har*_*rdy 9

JPA 2定义了javax.persistence.query.timeout提示以指定默认超时(以毫秒为单位).Hibernate 3.5(目前仍处于测试阶段)将支持此提示.

另见https://hibernate.atlassian.net/browse/HHH-4662


Reh*_*ron 5

JDBC具有一种称为查询超时的机制,您可以调用java.sql.Statement对象的setQueryTime方法来启用此设置。

Hibernate无法以统一的方式执行此操作。

如果您的应用程序通过java.sql.DataSource检索JDBC连接,则可以轻松解决该问题。

我们可以创建一个DateSourceWrapper来代理Connnection,该代理对创建的每个Statement进行setQueryTimeout。

示例代码易于阅读,我使用一些spring util类来帮助实现这一点。

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;
}
Run Code Online (Sandbox Code Playgroud)

}

现在,我们可以使用此QueryTimeoutConfiguredDataSource来包装您现有的DataSource,以透明地为每个语句设置Query Timeout!

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>
Run Code Online (Sandbox Code Playgroud)