Hibernate调试——定位查询源头

标签: 基础技术 Hibernate 调试 | 发表时间:2014-07-08 08:00 | 作者:jessenpan
出处:http://www.importnew.com

为什么有时Hibernate会在程序某一部分生成一条指定sql查询?这个问题让人很难立刻理解,当处理不是我们本人编写的代码时更是如此。

本文将展示如何配置来产生Hibernate查询操作的日志。通过这些日志和一些小技巧来找出这些指定的查询为什么及在何处被执行。

Hibernate查询日志格式

Hibernate内建的查询日志格式如下:

select /* load your.package.Employee */ this_.code, ... 
from employee this_ 
where this_.employee_id=?

TRACE 12-04-2014@16:06:02  BasicBinder - binding parameter [1] as [NUMBER] - 1000

为什么Hibernate不能记载最终的查询日志?

需要注意的是,Hibernate只记录从它发送到JDBC的准备语句(prepared statement)及参数。准备语句使用“?”作为查询参数的占位符,这些参数的实际值被记录在准备语句的下方。

这些准备语句和最终发送到数据库的sql语句是不同的,对于这些最终的查询操作Hibernate无法记录。出现这种情况的原因是Hibernate只知道它发送给JDBC的准备语句和参数,实际的查询是由JDBC构建并发送给数据库的。

为了产生实际查询的日志,像log4jdbc这种工具是必不可少的,这里不会讨论如何使用log4jdbc。

如何找到原始查询操作

上述的可记录查询包含一条标注,在大多数情况下它可以标识某条起始查询语句。如果一条查询是由加载引起的,那么标注便是/*load your.entity.Name*/。如果是一条命名查询,那么标注则包含查询的名称。

如果它是一个对应许多延迟加载的查询,标注则会包含对应类的名称和引发该操作的属性值等。

设置Hibernate的查询日志

为了获得查询日志,需要将如下标签加入会话工厂的配置文件中:

<bean id= "entityManagerFactory" >
  ...
  <property name="jpaProperties" >
  <props>
      <prop key="hibernate.show_sql" >true</ prop>
      <prop key="hibernate.format_sql" >true</ prop>
      <prop key="hibernate.use_sql_comments">true</prop>
  </props>
</property>

上面的示例展示了Spring实体管理工厂的配置。下面是对一些标签的解释:

  • show_sql:激活查询日志功能。
  • format_sql:优雅地输出Sql。
  • use_sql_comments:添加一条解释型标注。

为了记录查询语句的参数信息,log4j或者相对应的信息是需要的。

<logger name="org.hibernate.type">
    <level value="trace" />
</logger >

如果上述功能都不能运行

在大多数情况下,use_sql_comments创建的标注是足够用来标识查询的起始。但如果这还不够,我们可以标识和数据表名相关联的查询返回的实体,并在返回的实体构造函数中设置断点。

如果一个实体没有构造函数,我们可以创建一个构造函数并把断点设置在super()函数调用中。

@Entity
public class Employee {
    public Employee() {
        super(); // put the breakpoint here
    }
    ...
}

设置断点后,跳转到包含程序堆栈信息的Debug界面并从头到尾执行一遍。这样在调用栈中将会出现查询操作在何处被创建。

相关文章

相关 [hibernate 调试 源头] 推荐:

Hibernate调试——定位查询源头

- - ImportNew
为什么有时Hibernate会在程序某一部分生成一条指定sql查询. 这个问题让人很难立刻理解,当处理不是我们本人编写的代码时更是如此. 本文将展示如何配置来产生Hibernate查询操作的日志. 通过这些日志和一些小技巧来找出这些指定的查询为什么及在何处被执行. Hibernate查询日志格式. Hibernate内建的查询日志格式如下:.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

Hibernate Lazy属性

- - 博客园_首页
  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术. 这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录. 通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销. Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.

hibernate优化

- - 开源软件 - ITeye博客
原文 http://developer.51cto.com/art/200906/129539.htm. 文章分为十三个小块儿对Hibernate性能优化技巧进行总结性分析,分析如下:. 一、在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session.

JPA & Hibernate 注解

- - CSDN博客编程语言推荐文章
必须,name为可选,对应数据库中一的个表 . 可选,通常和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息 . name:可选,表示表的名称.默认地,表名和实体名称一致,只有在不一致的情况下才需要指定表名 . catalog:可选,表示Catalog名称,默认为Catalog(""). .

hibernate 大对象类型的hibernate映射

- - CSDN博客推荐文章
在 Java 中, java.lang.String 可用于表示长字符串(长度超过 255), 字节数组 byte[] 可用于存放图片或文件的二进制数据. 此外, 在 JDBC API 中还提供了 java.sql.Clob 和 java.sql.Blob 类型, 它们分别和标准 SQL 中的 CLOB 和 BLOB 类型对应.

JBoss发布Hibernate 4.0

- - InfoQ cn
近日, JBoss发布了流行的对象/关系(O/R)映射框架 Hibernate. Hibernate 4主要的新特性如下所示:. 引入了“Services”API. 提供了更棒的日志,支持 i18n与消息编码(通过JBoss Logging而非 slf4j). 为 OSGi支持做好了准备.

快速上手Hibernate

- - CSDN博客推荐文章
在前面我们已经对Hibernate有所了解,并知道了使用Hibernate的好处,下面就给大家展示一下如何快速使用Hibernate:. 1.下载Hibernate,并解压缩(下载地址: http://www.hibernate.org/downloads). 2.创建一个新的Java项目.   加入数据库驱动(以mysql示例).

Hibernate 二级缓存

- - CSDN博客推荐文章
很多人对二级缓存都不太了解,或者是有错误的认识,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了. 我的经验主要来自hibernate2.1版本,基本原理和3.0、3.1是一样的,请原谅我的顽固不化. hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了.