大家晚上好,我在api Criteria中使用addOrder方法有一个奇怪的问题,oracle抛出ORA-02393:超出CPU使用率的限制,我使用下面的类与hibernate 4.1.4和oracle 11g express版:
public class Atendido {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL })
@JoinColumn(name = "ID_PESSOA_FISICA")
private PessoaFisica pessoaFisica;
@OneToOne(fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL })
@JoinColumn(name = "ID_PESSOA_JURIDICA")
private PessoaJuridica pessoaJuridica;
@OneToMany(fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL }, orphanRemoval = true)
@BatchSize(size = 50)
@JoinColumn(name = "ID_ATENDIDO")
private List<RgCriminal> rgs;
.
.
//getters and setters
}
public class PessoaFisica {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Column(name = "NOME_PAI")
private String nomePai;
@Column(name = "NOME_NASCIMENTO")
private String nomeNascimento;
@Column(name = "NOME_MAE")
private String nomeMae;
@Column(name = "NOME_SOCIAL")
private String nomeSocial;
.
.
//getters and setters
}
public class PessoaJuridica {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Column(name = "RAZAO_SOCIAL")
private String razaoSocial;
@Column(name = "NOME_FANTASIA")
private String nomeFantasia;
@Column(name = "REPRESENTANTE_LEGAL")
private String representanteLegal;
.
.
//getters and setters
}
public class RgCriminal {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Column(name = "RG_CRIMINAL")
private String rgCriminal;
.
.
//getters and setters
}
现在我有以下方法来搜索Atendido类
@SuppressWarnings("unchecked")
private List<Atendido> listAll(String term, Integer firstResult,
Integer maxResults) throws ParseException {
Criteria criteria = this.session.createCriteria(Atendido.class);
criteria.createCriteria("pessoaFisica", "pessoaFisica",
JoinType.LEFT_OUTER_JOIN);
criteria.createCriteria("pessoaJuridica", "pessoaJuridica",
JoinType.LEFT_OUTER_JOIN);
criteria.createCriteria("rgs", "rg", JoinType.LEFT_OUTER_JOIN);
Disjunction or = Restrictions.disjunction();
for (String token : term.split(";")) {
token = token.trim();
if (!StringUtils.isEmpty(token)) {
//my.Restrictions.ilike is my implementation to ignore accentuation , follow class below
or.add(my.Restrictions
.ilike("pessoaFisica.nomeNascimento", token,
MatchMode.ANYWHERE));
or.add(my.Restrictions
.ilike("pessoaFisica.nomeSocial", token,
MatchMode.ANYWHERE));
or.add(my.Restrictions
.ilike("pessoaJuridica.nomeFantasia", token,
MatchMode.ANYWHERE));
or.add(my.Restrictions
.ilike("pessoaJuridica.razaoSocial", token,
MatchMode.ANYWHERE));
or.add(my.Restrictions
.ilike("pessoaJuridica.representanteLegal",
token, MatchMode.ANYWHERE));
or.add(my.Restrictions
.ilike("pessoaFisica.nomeMae", token,
MatchMode.ANYWHERE));
}
}
criteria.add(or);
if (firstResult != null && maxResults != null) {
criteria.setFirstResult(firstResult).setMaxResults(maxResults);
} else if (maxResults == null) {
criteria.setMaxResults(50);
} else {
criteria.setMaxResults(maxResults);
}
/* if comment this block execution ocurrs about 2 seconds , if i uncomment this block oracle returns a error ORA-02393: exceeded call limit on CPU usage because the execution ocurrs more than 20 seconds . It's a kind of bug ?
criteria.addOrder(Order.asc("pessoaFisica.nomeMae"));
criteria.addOrder(Order.asc("pessoaFisica.nomeNascimento"));
criteria.addOrder(Order.asc("pessoaJuridica.razaoSocial"));
*/
return criteria.list();
}
public class LikeExpression implements Criterion {
private static final long serialVersionUID = 1L;
private final String propertyName;
private final Object value;
private final Character escapeChar;
private final boolean ignoreCase;
public LikeExpression(String propertyName, String value,
Character escapeChar, boolean ignoreCase) {
this.propertyName = propertyName;
this.value = value;
this.escapeChar = escapeChar;
this.ignoreCase = ignoreCase;
}
protected LikeExpression(String propertyName, String value) {
this(propertyName, value, null, false);
}
protected LikeExpression(String propertyName, String value,
MatchMode matchMode) {
this(propertyName, matchMode.toMatchString(value));
}
protected LikeExpression(String propertyName, String value,
MatchMode matchMode, Character escapeChar, boolean ignoreCase) {
this(propertyName, matchMode.toMatchString(value), escapeChar,
ignoreCase);
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
String searchFor = "áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ";
String replaceTo = "aaaaaeeeooooouuucaaaaeeeoooouuuc";
Dialect dialect = criteriaQuery.getFactory().getDialect();
String[] columns = criteriaQuery.findColumns(propertyName, criteria);
if (columns.length != 1) {
throw new HibernateException(
"Like may only be used with single-column properties");
}
String escape = escapeChar == null ? "" : " escape \'" + escapeChar
+ "\'";
String column = columns[0];
if (ignoreCase) {
if (dialect.supportsCaseInsensitiveLike()) {
return "translate(" + column + ",'" + searchFor + "','"
+ replaceTo + "')" + dialect.getCaseInsensitiveLike() + " ?"
+ escape;
} else {
return dialect.getLowercaseFunction() + '(' + "translate(" + column + ",'" + searchFor + "','"
+ replaceTo + "')" + ')'
+ " like ?" + escape;
}
} else {
return "translate(" + column + ",'" + searchFor + "','"
+ replaceTo + "') like ?" + escape;
}
}
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { criteriaQuery.getTypedValue(
criteria,
propertyName,
ignoreCase ? StringUtil.removeAccentuation(value.toString()
.toLowerCase()) : StringUtil.removeAccentuation(value
.toString())) };
}
}
public class Restrictions {
public static Criterion ilike(String propertyName, String value,MatchMode matchMode) {
return new LikeExpression(propertyName, value, matchMode, null, true);
}
}
生成查询
select
*
from
( select
*
from
ATENDIDO this_
left outer join
PESSOA_FISICA pessoafisi1_
on this_.ID_PESSOA_FISICA=pessoafisi1_.ID
left outer join
PESSOA_JURIDICA pessoajuri2_
on this_.ID_PESSOA_JURIDICA=pessoajuri2_.ID
left outer join /* this is a list*/
RG_CRIMINAL rgs3_
on this_.ID=rgs3_.ID_ATENDIDO
where
(
lower(translate(pessoafisi1_.NOME_NASCIMENTO,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
or lower(translate(pessoafisi1_.NOME_SOCIAL,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
or lower(translate(pessoajuri2_.NOME_FANTASIA,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
or lower(translate(pessoajuri2_.RAZAO_SOCIAL,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
or lower(translate(pessoajuri2_.REPRESENTANTE_LEGAL,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
or lower(translate(pessoafisi1_.NOME_MAE,'áàâãªéèêóòôõºúùûçÁÀÂÃÉÈÊÓÒÔÕÚÙÛÇ','aaaaaeeeooooouuucaaaaeeeoooouuuc')) like ?
)
order by
pessoafisi1_.NOME_MAE asc,
pessoafisi1_.NOME_NASCIMENTO asc,
pessoajuri2_.RAZAO_SOCIAL asc )
where
rownum <= ?
和堆栈跟踪
18:26:43,549 br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: org.hibernate.exception.GenericJDBCException: ORA-02393: limite de chamada excedido no uso de CPU (call limit cpu exceed)
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:96)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.gov.sp.defensoria.sia.interceptor.PaginateInterceptor.intercept(PaginateInterceptor.java:55)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.gov.sp.defensoria.sia.interceptor.RestrictInViewInterceptor.intercept(RestrictInViewInterceptor.java:48)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.gov.sp.defensoria.sia.interceptor.RestrictInterceptor.intercept(RestrictInterceptor.java:53)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.gov.sp.defensoria.sia.interceptor.AuthenticationInterceptor.intercept(AuthenticationInterceptor.java:37)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:93)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.gov.sp.defensoria.sia.interceptor.ErrorInterceptor.intercept(ErrorInterceptor.java:47)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.environment.EnvironmentInterceptor.intercept(EnvironmentInterceptor.java:37)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.plugin.hibernate4.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:33)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
引起:org.hibernate.exception.GenericJDBCException:ORA-02393:limite de chamada excedido no uso de CPU(超出呼叫限制cpu)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy106.executeQuery(Unknown Source)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doList(Loader.java:2438)
at org.hibernate.loader.Loader.doList(Loader.java:2424)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2254)
at org.hibernate.loader.Loader.list(Loader.java:2249)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:122)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1622)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
at br.gov.sp.defensoria.sia.repository.impl.AtendidoRepositoryImpl.listAll(AtendidoRepositoryImpl.java:136)
at br.gov.sp.defensoria.sia.repository.impl.AtendidoRepositoryImpl.search(AtendidoRepositoryImpl.java:49)
at br.gov.sp.defensoria.sia.controller.AtendidoController.list(AtendidoController.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
... 62 more
引起:java.sql.SQLException:ORA-02393:limite de chamada excedido no uso de CPU
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1062)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:839)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1132)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
... 82 more
{
term:juliane,}
实际上oracle的配置文件“DEFAULT”LIMIT CPU_PER_CALL 1500(15秒)。
我的表atendido(对于Atendido类)有超过400.000行。如果我在oracle客户端运行hibernate生成的sql有或没有“order by”似乎是正常的,没有执行问题。任何人都可以在评论和取消注释包含addOrder方法的块时解释这种奇怪的行为吗?
由于