我最近意识到一个应用程序消耗的内存超出了它应该消耗的内存。我对JVM进行了线程转储,发现Hibernate SessionFactoryImpl中有数百兆字节的SQL查询。
这些查询出现在刚刚启动应用程序服务器的内存中。我已经在后台放弃了队列(JMS)或其他进程的假设。
查询有以下两种格式:
select
diferenc0_.id as id975_137_,
[...]
where diferenc0_.id=?
或
select
diferenc0_.id as id975_137_,
[...]
where diferenc0_.id= IN (?,?,?,?,?,?,?,?) -- because default_batch_fetch_size = 8
我的persistence.xml配置(我关闭了hbm2ddl):
"hibernate.hbm2ddl.auto", ""
"hibernate.query.startup_check", "false"
"hibernate.show_sql", "false"
"hibernate.format_sql", "false"
"hibernate.transaction.auto_close_session", "true"
"hibernate.cache.use_second_level_cache", "false"
"hibernate.cache.use_query_cache", "false"
"hibernate.jdbc.batch_size", "20"
"hibernate.default_batch_fetch_size", "8"
我使用的是Hibernate 3.3.0。
另一个重要的细节是:这些查询不会发送到数据库!我与我们团队的DBA一起分析了Jboss启动时发送到数据库的查询。我们还在系统中不使用命名查询。
作为一个有点老的应用程序,老的开发人员在映射中使用了fetch EAGER资源。因此,这些生成的查询非常庞大。
问题:当应用程序启动时,Hibernate在内存中创建这些查询的目的是什么?
您可以尝试添加此属性:
"hibernate.temp.use_jdbc_metadata_defaults","false"
并删除
"hibernate.hbm2ddl.auto", ""