如何使用JPA和Hibernate设置默认查询超时?
2022-09-03 13:58:35
我正在使用Hibernate对数据库进行一些大查询,有时会遇到超时。我想避免在每个 或 上手动设置超时。Query
Criteria
是否有任何属性可以提供给我的休眠配置,以便为我运行的所有查询设置可接受的默认值?
如果没有,如何在休眠查询上设置默认超时值?
我正在使用Hibernate对数据库进行一些大查询,有时会遇到超时。我想避免在每个 或 上手动设置超时。Query
Criteria
是否有任何属性可以提供给我的休眠配置,以便为我运行的所有查询设置可接受的默认值?
如果没有,如何在休眠查询上设置默认超时值?
JPA 2 定义了 javax.persistence.query.timeout 提示,以指定以毫秒为单位的缺省超时。Hibernate 3.5(目前仍处于测试阶段)将支持此提示。
JDBC 有这个名为 Query Timeout 的机制,你可以调用 java.sql.Statement 对象的 setQueryTime 方法来启用此设置。
Hibernate不能以统一的方式做到这一点。
如果您的应用程序检索 JDBC 连接 vi java.sql.DataSource,则可以轻松解决此问题。
我们可以创建一个DateSourceWrapper来代理Connnection,它为它创建的每个语句设置QueryTimeout。
示例代码易于阅读,我使用一些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;
}
}
现在我们可以使用此QueryTimeoutConfiguredDataSource来包装您现有的数据源,以透明地为每个语句设置查询超时!
弹簧配置文件:
<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>