我的软件有这个奇怪的问题.是生产了5年,我们没有这样的问题......
问题:
我们有一个spring job(scheduler),它通过hibernate进行查询,检索对象并修改它们.
好吧,这工作了几年,但一个月前查询每天挂起5-10次(每10分钟调用一次查询).当它挂起时,我们必须重新启动服务.
以下代码执行查询:
@SuppressWarnings("unchecked")
public List<Delivery> findScheduledForDelivery(final String inType, final int max, final String benefitType ) {
//getHibernateTemplate().clear();
return getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws SQLException {
Criteria criteria = session.createCriteria(Delivery.class);
criteria.createAlias("reward","r");
criteria.createAlias("r.customer","c");
criteria.createAlias("c.inNe","i");
criteria.createAlias("r.promotion","p");
criteria.createAlias("benefit","b");
String sqlCustAlias = StringHelper.generateAlias("c", 2);
criteria.add(Expression.disjunction()
.add(Expression.eq("inStatus", INStatus.InterfaceFailure))
.add(Expression.eq("inStatus",INStatus.Initial)));
criteria.add(Expression.le("deliverAt", new Date()));
String dateString = "2000/01/01";
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
Date startDate = new Date();
try {
startDate = dateFormat.parse(dateString);
criteria.add(Expression.ge("deliverAt", startDate));
}
catch(ParseException e) {
e.printStackTrace();
} …Run Code Online (Sandbox Code Playgroud) 我在Oracle上检测到hibernate和本机查询的性能问题.当我在TOAD上执行带有多个参数的复杂SQL查询时,我得到的结果是毫秒.但是,当我使用Hibernate执行相同的查询时,此时间会大幅增加(最多四秒甚至更多).
我的SQL查询相当复杂,返回一个唯一值(因此,问题与实现类所需的时间无关),它包含几个参数格式为':nameParameter'.此查询存储在String中.例如,
String myNamedNativeQuery = "select count(*) from tables "+
"where column1 = :nameParameter1 "+
"and column2 = :nameParameter2";
//actually my sentence is much more complex!!
Run Code Online (Sandbox Code Playgroud)
当我在TOAD上执行句子时,它会在几毫秒内解决.但是用Hibernate这个句子
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.setParameter(nameParameter1, value1);
query.setParameter(nameParameter2, value2);
query.uniqueResult();
Run Code Online (Sandbox Code Playgroud)
需要几秒钟才能得到相同的结果.
我意识到如果我直接在原生查询中替换参数然后我使用Hibernate执行句子,时间会急剧减少.它会是这样的:
String strQuery = session.getNamedQuery("myNamedNativeQuery").getQueryString();
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter1", value1);
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter2", value2);
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.uniqueResult();
Run Code Online (Sandbox Code Playgroud)
谁知道发生了什么?
提前致谢.
PS:Oracle版本是9i和Hibernate 3.2