hibernate的hql中的java常量会引起性能问题 博客分类: hibernate
程序员文章站
2024-03-16 17:02:16
...
在多线程环境中,hibernate把hql转换为sql时,会频繁的调用classloader中的方法来加载class。在某些中间件中(例如tomcat),classloader在加载class时,是同步操作。这种组合大大降低了应用程序的性能。
相关文章
https://hibernate.atlassian.net/browse/HHH-10746
https://hibernate.atlassian.net/browse/HHH-4959
在hibernate 5.2.6版中,修改了这个问题,增加了配置
hibernate.query.conventional_java_constants
默认值为true,即在hql中不支持java常量的引用
例如:
from Table t where t.c_bh=com.xxx.Table.N_XXX
不会尝试解析“t.c_bh”,但是会尝试解析“com.xxx.Table.N_XXX”
之前版本的hibernate,在hql中碰到“xx.xx”时,都会调用classloader来尝试加载类,这个会导致classloader加载很多不存在的类(调用开销大),这是导致性能下降的原因。
堆栈1:
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:390) - waiting to lock <0x00000007315a3870> (a org.eclipse.jetty.webapp.WebAppClassLoader) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383) at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:95) at org.hibernate.util.ReflectHelper.getConstantValue(ReflectHelper.java:122) at org.hibernate.hql.ast.QueryTranslatorImpl$JavaConstantConverter.handleDotStructure(QueryTranslatorImpl.java:569) at org.hibernate.hql.ast.QueryTranslatorImpl$JavaConstantConverter.visit(QueryTranslatorImpl.java:564) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:40) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:42) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:42) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:41) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:42) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:41)
堆栈2:
at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:171) at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:100) at org.hibernate.util.ReflectHelper.getConstantValue(ReflectHelper.java:122) at org.hibernate.hql.ast.QueryTranslatorImpl$JavaConstantConverter.handleDotStructure(QueryTranslatorImpl.java:569) at org.hibernate.hql.ast.QueryTranslatorImpl$JavaConstantConverter.visit(QueryTranslatorImpl.java:564) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:40) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:41) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:41) at org.hibernate.hql.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:41) at org.hibernate.hql.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:33) at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:254) at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)