休眠日志:常见问题的提示和解决方案

如何通过适当的日志记录解决一些最常见的Hibernate问题?

Hibernate的日志记录配置是一个重要但很少讨论的主题。 正确的配置可以帮助您在开发过程中发现潜在的问题,而错误的配置则可以在生产中导致严重的性能问题。 这就是我在新书《 Hibernate提示》中解释不同配置选项的原因之一 常见的Hibernate问题有70多种解决方案

在本文中,我们将分享本书中最有用的2个Hibernate日志记录技巧。 让我们开始吧。

1.解决最常见的Hibernate性能问题

让我们看一下本书中包含的食谱之一。 它可以帮助您在开发过程中找到n + 1个选择问题。 当Hibernate必须初始化实体之间的延迟获取的关联时,经常会发生此性能问题。 不幸的是,在源代码中很难找到此问题,因为您只需调用映射关联的属性的getter方法,例如author.getBooks()即可 。 如果在循环访问Author实体列表的循环中执行此操作,则Hibernate必须执行1个查询以加载n个Author实体,并执行n个其他查询来初始化关联。 这就是n + 1选择问题,它是最常见的性能问题之一。

您可以通过激活Hibernate的Statistics组件找到它,该组件提供了一种简单的方法来对Hibernate Session中所有已执行的查询进行计数。 让我们看看它是如何完成的。

如何计算会话中已执行的查询

问题

我的一些用例很慢,似乎执行了太多查询。

如何计算在Hibernate 会话中执行的所有查询?

计算所有已执行查询的最简单方法是激活Hibernate的统计信息组件。 然后,Hibernate收集了大量内部统计数据,并将它们作为日志消息并通过Statistics API提供。

警告:请勿在生产中使用该产品! 收集统计信息会产生开销,从而降低您的应用程序速度。

默认情况下,Hibernate的统计信息组件处于禁用状态。 您可以通过将hibernate.generate_statistics参数设置为true来激活它。 您可以通过提供具有相同名称的系统属性或通过在persistence.xml文件中设置参数来执行此操作。

<persistence><persistence-unit name="my-persistence-unit"><description>Hibernate Tips</description><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><properties><property name="hibernate.generate_statistics" value="true" />…</properties></persistence-unit>
</persistence>

您有两个选项可以访问统计信息。 Hibernate可以将每个会话的最重要信息的子集写入日志文件,或者您可以通过Statistics API访问它们。

让我们先来看一下日志消息。 Hibernate在每个会话结束时会写一条类似于以下内容的日志消息。 它显示了SQL语句的数量,准备和执行它们所花费的时间以及与第二级缓存的交互。

16:24:55,318 INFO [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] – Session Metrics {25659 nanoseconds spent acquiring 1 JDBC connections;22394 nanoseconds spent releasing 1 JDBC connections;1091216 nanoseconds spent preparing 12 JDBC statements;11118842 nanoseconds spent executing 12 JDBC statements;0 nanoseconds spent executing 0 JDBC batches;0 nanoseconds spent performing 0 L2C puts;0 nanoseconds spent performing 0 L2C hits;0 nanoseconds spent performing 0 L2C misses;16999942 nanoseconds spent executing 1 flushes (flushing a total of 17 entities and 17 collections);63915 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)

您还可以通过Hibernate的Statistics界面访问Statistics API。 您可以从SessionFactory获取它。 它提供了几种获取方法,使您可以访问比日志输出更详细的信息。

Statistics stats = sessionFactory.getStatistics();
long queryCount = stats.getQueryExecutionCount();
long collectionFetchCount = stats.getCollectionFetchCount();

源代码

在本书中,您可以找到带有可执行测试用例的项目的下载链接,其中包含可执行的测试用例。

学到更多

如果您想了解有关Hibernate日志记录功能的更多信息,请查看以下章节:

  • 如何记录SQL语句及其参数
  • 如何使用查询注释来识别查询

=============

计算已执行的查询可以帮助发现效率低下和避免性能问题。 但这还不够。 您还需要知道Hibernate执行哪些查询以及它使用哪些参数值。 使用正确的日志记录配置,Hibernate会将所有这些信息写入日志。

=============

2.如何记录SQL语句及其参数

问题

您如何配置Hibernate,使其将已执行的SQL语句和已使用的绑定参数写入日志文件?

Hibernate使用两种不同的日志类别和日志级别来记录已执行的SQL语句及其绑定参数:

  • SQL语句作为DEBUG消息写入类别org.hibernate.SQL
  • 绑定参数值以日志级别TRACE记录到org.hibernate.type.descriptor.sql类别中。

您可以在日志配置中相互独立地激活和停用它们。

警告:记录所有SQL查询及其绑定参数绑定会减慢您的应用程序的速度并创建巨大的日志文件。

您不应该在生产中激活这些日志消息。

以下代码段显示了一个可同时激活两者的log4j配置示例。

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%nlog4j.rootLogger=info, stdout
# basic log level for all messages
log4j.logger.org.hibernate=info# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type.descriptor.sql=trace

然后,Hibernate将类似于以下内容的日志消息写入您的日志文件。

17:34:50,353 DEBUG [org.hibernate.SQL] - select author0_.id as id1_0_, author0_.firstName as firstNam2_0_, author0_.lastName as lastName3_0_, author0_.version as version4_0_ from Author author0_ where author0_.id=1
17:34:50,362 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([id1_0_] : [BIGINT]) - [1]
17:34:50,373 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([firstNam2_0_] : [VARCHAR]) - [Thorben]
17:34:50,373 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([lastName3_0_] : [VARCHAR]) - [Janssen]
17:34:50,374 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([version4_0_] : [INTEGER]) - [0]

代码段中的SQL语句不容易阅读。 当您告诉Hibernate格式化它时,情况会好得多。

您可以通过将配置参数hibernate.format_sql设置为true实现 。 您可以将其提供为系统属性,也可以在persistence.xml文件中进行设置,例如以下代码片段,或在hibernate.cfg.xml文件中进行设置。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence><persistence-unit name="my-persistence-unit"><description>Hibernate Tips</description><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><exclude-unlisted-classes>false</exclude-unlisted-classes><properties><property name="hibernate.format_sql" value="true" />...</properties></persistence-unit>
</persistence>

下面的代码片段显示了格式化的SQL语句,它比上一条消息更易于阅读。

16:42:56,873 DEBUG [org.hibernate.SQL] -selectauthor0_.id as id1_0_,author0_.firstName as firstNam2_0_,author0_.lastName as lastName3_0_,author0_.version as version4_0_fromAuthor author0_whereauthor0_.id=?
16:42:56,926 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [BIGINT] - [1]
16:42:56,950 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([id1_0_] : [BIGINT]) - [1]
16:42:56,965 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([firstNam2_0_] : [VARCHAR]) - [Thorben]
16:42:56,965 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([lastName3_0_] : [VARCHAR]) - [Janssen]
16:42:56,966 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([version4_0_] : [INTEGER]) - [0]

源代码

在本书中,您可以找到带有可执行测试用例的项目的下载链接,其中包含可执行的测试用例。

使您的日志更好

如前所述,激活TRACE和DEBUG级别的消息并将其发送到您的日志可能会导致文件很大,甚至可能减慢您的应用程序的速度。 但是,它们可能包含对于调试过程至关重要的信息,并且可以帮助在关键错误投产之前确定关键错误。

OverOps向您显示在错误之前在生产中记录的最后250个DEBUG,TRACE和INFO级别的语句,即使它们已关闭并且从未到达日志文件。 它还显示任何异常,记录的错误或警告背后的变量状态,而无需依赖实际记录的信息。 您可以在错误的整个调用堆栈中看到完整的源代码和变量状态,甚至在微服务和计算机上也可以看到。

探索调试生产错误的新方法。 观看OverOps的现场演示 。

结论

有关更多类似的食谱,请查看我的新书《 Hibernate Tips:70多种常见Hibernate问题的解决方案》 。 它为您提供了70多个现成的食谱,用于基本和高级映射,日志记录,Java 8支持,缓存以及静态和动态定义的查询等主题。 几天之内,您可以在hibernate-tips.com上以$ 2.99的价格获得电子书,以$ 12.99的价格获得平装本。

翻译自: https://www.javacodegeeks.com/2017/04/hibernate-logging-tips-solutions-common-problems.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/350984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jdbc工具类2..0

一、创建外部文件 urljdbc:mysql:///qy66 useroot passwordroot drivercom.mysql.jdbc.Driver 二、创建工具类 package cn.zhouzhou;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.sql.Con…

matlab 获取系统时间now,date

&#xff08;1&#xff09; 直接在命令窗输入now&#xff0c;返回数字&#xff0c;这个数字一般无意义&#xff1b;输入date&#xff0c;返回具体日期&#xff1a; >> now ans 7.3699e05 >> date ans 23-Oct-2017 &#xff08;2&#xff09;想要将时间精确…

bash shell脚本访问PostgreSQL的三种方式

bash脚本里有三种方式访问PostgreSQL数据库 但前提是要设置密码文件。当然对于有系统对应账户的数据库角色可以绕过密码登录环节&#xff0c;如 1$ sudo -u postgres psql或 12$ sudo su - postgres$ psql但是对于没有系统账户对应的数据库角色&#xff0c;如要使用脚本登录则…

linux-shell-命令总结

第一种方法执行&#xff1a; 第二种方法执行&#xff1a; 第三种方法执行&#xff1a; 第四种方法&#xff1a;执行 第三种和第四种方法都是在新的进程里执行程序 函数方法 方法就是一个命令&#xff0c;命令写在字符串的第一个位置 type&#xff1a;可以接外部命令&#xff0c…

matlab plot绘制曲线

1)语法 plot(Y) plot(X1,Y1,…) plot(X1,Y1,LineSpec,…) plot(…,’PropertyName’,PropertyValue,…) plot(axes_handle,…) h plot(…) hlines plot(‘v6’,…) 2)说明 plot(Y)如果Y是mn的数组&#xff0c;…

【转】iPython入门技巧

【转】http://www.cnblogs.com/cuiyubo/p/6823478.html 学习《利用python进行数据分析》 第三章 IPython:一种交互式计算和开发环境的笔记&#xff0c;共享给大家&#xff0c;同时为自己作为备忘用。 安装ipython用pip即可。ps.博主用的是win7系统&#xff0c;所以接下来的都是…

进程控制:进程的创建、终止、阻塞、唤醒和切换

进程控制的主要功能是对系统中的所有进程实施有效的管理&#xff0c;它具有创建新进程、撤销已有进程、实现进程状态转换等功能。在操作系统中&#xff0c;一般把进程控制用的程序段称为原语&#xff0c;原语的特点是执行期间不允许中断&#xff0c;它是一个不可分割的基本单位…

jnlp下载

下载.jnlp文件里的内容需先安装好java Java安装好&#xff0c; java环境变量配置http://jingyan.baidu.com/article/4ae03de320d99f3eff9e6bfd.html 打开cmd&#xff08;WinR&#xff09;如下输入javaws \文件路径\ TCIA_REMBRANDT_06-22-2015.jnlp 后&#xff0c;按回车: 按…

使用Dagger 2在GWT中进行依赖注入

依赖注入是一种软件开发概念&#xff0c;其中为对象提供了创建所需的所有对象或值。 GWT用户已经熟悉GIN&#xff0c;但已不推荐使用此工具&#xff0c;因此不再支持&#xff0c;因此使用GIN的应用程序当前确实需要告别。 Dagger是GWT的新依赖注入框架。 对于那些不熟悉该框架的…

Java Web Token - JWT

JWT认证过程&#xff1a;https://www.codetd.com/article/3602378 JWT官方文档&#xff1a;https://jwt.io/introduction/转载于:https://www.cnblogs.com/leodaxin/p/10648358.html

中断和异常,陷阱的区别和联系

对于中断&#xff0c;异常和陷阱的各种关系&#xff0c;总结如下&#xff1a; 表 2.1. 中断&#xff0c;异常和陷阱的区别和联系 对CPU来说是 和当前CPU所执行的指令的关系CPU接下来的事情程序员和用户的态度中断被动的异步的没关系跳转到对应的ISR希望有对应的中断&#xff0c…

matlab global(全局变量)

如果想让某个函数中定义的变量能够被其他函数调用&#xff0c;需要用到全局变量。注意&#xff0c;在这两个函数中都要用global修饰这个变量。如&#xff1a; function t1 global x; x0; function t2 global x; yx end

win 2016 ssh_多台WIN10之间的SSH免密登录

网上有很多关于使用win10-ssh客户端登录linux-ssh服务端的介绍&#xff0c;但很少介绍多台win10-ssh服务端之间互访的。以下记录如何免密登录win10-ssh服务。1、安装OpenSSH。网上有很多介绍通过添加win10可选功能安装openssh&#xff0c;此处不赘述。如果通过添加可选功能出现…

Windows下安装及使用NVM

所谓nvm就是一个可以让你在同一台机器上安装和切换不同版本node的工具。这里是一篇安装及使用教程。 第一步&#xff1a;下载nvm 到github上下载最新版本https://github.com/coreybutler/nvm-windows/releases nvm-noinstall.zip&#xff1a; 这个是绿色免安装版本&#xff0c;…

Operating System-Thread(5)弹出式线程使单线程代码多线程化会产生那些有关问题

Operating System-Thread(5)弹出式线程&&使单线程代码多线程化会产生那些问题本文主要内容 弹出式线程&#xff08;Pop-up threads)使单线程代码多线程化会产生那些问题 一、弹出式线程&#xff08;Pop-up threads) 以在一个http到达之后一个Service的处理为例子来介绍…

cad2016中选择全图字体怎么操作_CAD2016 软件安装教程

安装包下载地址[软件名称]: CAD 2016[安装环境]: Win 10/Win 8/Win 7/Win xp[CAD2016 32-64bit下载链接]:https://pan.baidu.com/s/1AaeIZrJ6IlvBg3QiY3apWw[提取码]&#xff1a;oqcg(建议复制粘贴链接与提取码)安装中有问题可以咨询微信&#xff1a;XYSHY2CAD 2016介绍AutoCAD…

JavaScipt30(第八个案例)(主要知识点:canvas)

承接上文&#xff0c;这是第8个案例&#xff0c;要实现的效果是按住鼠标不放&#xff0c;进行拖动时可以在画布上画出不同粗细不同颜色的曲线。 附上项目链接: https://github.com/wesbos/JavaScript30 主要思路&#xff1a;鼠标按下时&#xff0c;记录当前x,y坐标&#xff0c;…

死锁的产生、预防和避免

死锁是由于并发进程只能按互斥方式访问临界资源等多种因素引起的&#xff0c;并且是一种与执行时间和速度密切相关的错误现象。死锁的一般定义&#xff1a;若在一个进程集合中&#xff0c;每一个进程都在等待一个永远不会发生的事件而形成一个永久的阻塞状态&#xff0c;这种阻…

python numpy.random模块中提供啦大量的随机数相关的函数

1. numpy中产生随机数的方法 1)rand()   产生[0,1]的浮点随机数,括号里面的参数可以指定产生数组的形状 2)randn()  产生标准正太分布随机数&#xff0c;参数含义与random相同 3)randint()  产生指定范围的随机数&#xff0c;最后一个参数是元祖&#xff0c;他确定数组的…