Как войти в спящий режим, какая часть кода вызвала данный SQL

#sql #spring #hibernate #jpa

#sql #spring #спящий режим #jpa

Вопрос:

Мы можем включить все связанные с SQL протоколирование со следующими настройками в spring:

 spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type=trace
 

Если у нас есть отдельная команда hibernate / springdata, например

 myEntityRepository.save(myEntity);
OR
enityManager.persist(myEntity);
 

тогда легко отладить то, что произошло, просто прочитав сгенерированный SQL из журнала.

Но как бы вы отлаживали, если нет какого-либо явного действия ORM, как здесь:

 @Transactional
void doHundredOfTask(Long id){
 MyEntity myEntity = myEntityRepository.findById(id);
 // here comes ton of action on the entity like settings field,setting/adding to collection
 // myEntity.setField1().. 
 //myEntity.setField2()
 //   ....
 // myEntity.setField_N()
 // myEntity.getSomeList.get(0).setSomeField()
 // no ORM action
}
 

В конце мы явно ничего не сохраняем, но после транзакции hibernate удалит изменения, следовательно, в журнале появится огромное количество SQL. Если у вас есть тонна действий над сущностью и ее ассоциациями, то крайне сложно отладить, почему был запущен данный SQL.

Есть ли способ присвоить сгенерированный SQL коду запуска в журнале?

редактировать: Правильно знаю, что все, что я могу сделать, это разделить код на более мелкие фрагменты / или закомментировать какую-то его часть. Но этот процесс медленный..

Ответ №1:

p6spy может печатать трассировку стека для каждого выполняемого оператора SQL. Вот конфигурация для включения этого: stacktrace=true .

Как настроить p6spy для проекта maven:

  1. Добавить зависимость p6spy
 <dependency>
  <groupId>p6spy</groupId>
  <artifactId>p6spy</artifactId>
  <version>3.9.1</version>
</dependency>
 
  1. Оберните соединение jdbc с помощью p6spy:
 spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/xxx
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
 
  1. Add spy.properties config src/main/resources/spy.properties
 stacktrace=true
appender=com.p6spy.engine.spy.appender.Slf4JLogger
logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat
 
  1. Вы можете удалить свойства, указанные ниже:
 spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
 

При такой конфигурации p6spy будет выводить SQL и stacktrace. Например.:

 select x0_.id as id1_7_ from X x0_
15:10:16.166 default [main] INFO  c.p.e.spy.appender.Slf4JLogger[logException]-39 - 
java.lang.Exception: null
    at com.p6spy.engine.common.P6LogQuery.doLog(P6LogQuery.java:126)
...
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2341)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2094)
...
    at com.springapp.Test.test(Test.java:36)
...