当我通过HQL加载包含许多列的ResultSets时,我对Hibernate的行为感到困惑:似乎一遍又一遍地调用 OracleStatement.getColumnIndex(String),而不是一次又一次地调用每一列加载但是在检索每行数据时每列一次。
如果ResultSet有很多列,这似乎需要花费大量时间(在我们的案例中,大约占总时间的43%,请参阅VisualVM配置文件的附加屏幕截图)。我们的HQL加载一个包含许多列的表,连接两个具有多对多关系的表(两者都有很多列)。遗憾的是,我们无法限制要加载的列,因为任务是在系统启动时将所有对象预加载到Coherence缓存中,因此必须完成对象。
据我所知,问题出现是因为从ResultSet中对HQL查询的映射结果对象进行保湿,对每个列使用nullSafeGet(),这些列使用String参数来标识列,因此必须调用getColumnIndex()。 (从SQL查询的ResultSet加载数据时,可以使用getString(int),getTimestamp(int)等而不是基于String的版本来避免此问题。)
我们仍在使用旧版本的Hibernate(3.6),但github上的源代码表明仍然存在相同的行为,因为nullSafeGet()仍然是基于String的,而不是采用索引(或包含索引的对象)然后可以在加载开始时预先计算一次。
我能在互联网上找到的唯一类似问题是this question没有答案。 那里的查询也有很多专栏。
感谢您的帮助!
和Thorsten
答案 0 :(得分:0)
此问题已在Hibernate 6中解决,它从按名称读取JDBC ResultSet转换为按位置读取。