2017-05-26 35 views
3

使用Hibernate(4.3.8)與MySQL,我發現服用大量的帶寬在活動日誌一堆SHOW WARNINGS聲明:如何從Hibernate禁用SHOW WARNINGS?

enter image description here

我搜索周圍,這是一個很常見的問題(for example),可以顯然可以通過increasing the log level to ERROR來解決(並且自從至少4.3.6以來該解決方案是confirmed implemented)。

問題是,我其實不知道該怎麼做。我對Hibernate的瞭解是關於使用它的最低必要條件。先前鏈接的帖子通過編輯logback.xml中的Logback設置來解決它,但我沒有使用Logback。我正在使用所有的默認設置:

  • 顯然它在其核心使用JBoss Logging
  • 我沒有任何其他的記錄依賴於我的類路徑(例如slf4j.jar),所以我絕對不會使用這些。日誌消息正在寫入System.err

所以我不確定如何做到這一點。這裏是我的配置文件:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
<hibernate-configuration>  
    <session-factory> 
     <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="connection.url">jdbc:mysql://localhost/xxxxx</property> 
     <property name="connection.username">xxxxx</property> 
     <property name="connection.password">xxxxx</property>  
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
     <property name="connection.isolation">2</property> 
     <property name="connection.pool_size">10</property> 
     <property name="current_session_context_class">thread</property> 
     <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 
     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
     <!-- <property name="show_sql">true</property> --> 
     <!-- <property name="hbm2ddl.auto">create</property> --> 
     <mapping resource="hibernate.hbm.xml"/>  
    </session-factory>  
</hibernate-configuration> 

這裏是構建路徑中的依賴關係;有拋棄和喬達,MySQL驅動程序,然後一切從Hibernate的required依賴目錄,沒有別的:

enter image description here

如何提高日誌級別,否則不啓動這個SHOW WARNINGS(默認設置) 案件? This提到「感興趣的日誌類別」,但我不確定這些與配置文件有關。 This page在「Logging」部分沒有提到任何與日誌有關的屬性,它提到SLF4J,但顯然我沒有使用SLF4J(我怎麼可能,因爲它不在我的類路徑中)。

+0

@ToanTran那是我掛在我解釋了爲什麼這種解決方案並沒有爲工作職位我。 :) –

+2

閱讀此:https://www.mkyong.com/hibernate/how-to-configure-log4j-in-hibernate-project/。然後查找'log4j.properties'文件或'log4j.xml'文件。 –

+0

@StephenC我明白了;好吧,只是爲了清楚其中的含義,基本上意味着我*不能*使用默認設置更改日誌警告級別,並且只能*如果配置了非默認日誌記錄工具(例如slf4j + log4j而不是jboss + system.err或其他)並設置相應的級別......對嗎? –

回答

0

好的。我瞭解了這一點,並在此過程中學到了很多東西。


TL; DR:

根據以下假設...

  • 沒有日誌記錄選項明確配置。
  • 類路徑中唯一與日誌相關的JAR是jboss日誌記錄(即沒有slf4j,log4j等)。

...休眠將automatically select JDK logging via JBoss Logging,和java.util.logging設施可用於控制日誌級別。因此,設置所有的JDK日誌的日誌級別SEVERE,在根記錄的水平(如果你之前或之後休眠初始化做到這一點並不重要,見下文)成功地停止SHOW WARNING命令:

LogManager.getLogManager().getLogger("").setLevel(Level.SEVERE); 

然而,這是一個霰彈槍的方法,它設置的所有註冊Logger的日誌級別,其級別設置爲null(從父級繼承)。


JDK日誌說​​明

我來到上述方案通過:

  1. 閱讀the logging doc幾次,直到它沉沒的,而什麼是班裏路徑信息相關聯,證據表明JDK日誌記錄正在使用中。
  2. 查看LogManager#getLoggerNames()的記錄器名稱列表。從Hibernate有不少,從這個確認點1.
  3. 我試圖找到負責SHOW WARNINGS,但不能。我知道它是而不是「org.hibernate.SQL」(更改日誌級別無效),它是而不是「org.hibernate」(該日誌實際上不存在)。
  4. 我打印出當前所有人的日誌水平,並注意到他們都是null(從父母繼承)。
  5. 我打印出層次結構,並看到根記錄器(名稱「」)是唯一一個日誌級別設置,所以我設置該日誌級別。請注意,因爲Hibernate日誌通常設置爲「繼承」,所以如果在配置Hibernate之前或之後執行此操作,則無關緊要:如果在執行日誌之前或之後執行該操作,則會記錄日誌,如果在執行日誌之後執行該操作在初始化過程中仍會看到它的輸出,並且可能會發出幾個SHOW WARNING,但這沒什麼大不了的。

所以這就是我如何到達上面,留下永久的以下草率,我仍然解決方案:

  • 鳥槍法,所以他們都禁用不知道到底是什麼記錄器負責。
  • 由於缺乏「org.hibernate」而感到困惑。
  • 這隻有在JDK日誌記錄正在使用時纔有效,它依賴於上述假設。將另一個支持的日誌框架放在你的​​類路徑中可能會導致Hibernate選擇一個不同的框架,從而導致解決方案失效。
  • 我只試過SEVERE,並驗證它正在工作。不同的日誌級別也可能工作,但我沒有測試。

其他注意事項

我想明確地找出了Hibernate的自動選擇哪個記錄,但無法確定該怎麼做(誰知道?)。我唯一的猜想是在ServiceRegistry中,但似乎沒有與日誌有關的Service,或者至少我找不到一個。

通常,它的更可預測的,以明確地配置一個記錄工具,然後根據其文檔配置它,如在溶液上方,例如,僅僅通過添加另一JAR到類路徑斷裂。 然而,快速/一次性/無關緊要的項目中,你只是減少配置文件和這樣的,這似乎是削減了SHOW WARNING命令的最簡單方法。

0

Hibernate框架中默認啓用了與發射每個查詢中的MySQL的SHOW警告,這個雙打查詢到MySQL和應用程序的數量可以實現性能問題。這種額外的由Hibernate SHOW警告的記錄可以在建立 -

org.hibernate.engine.jdbc.spi.SqlExceptionHelper#handleAndClearWarnings() 

解決方案

製作休眠選擇合適的記錄。這可以通過添加: -Dorg.jboss.logging.provider=slf4j-Dorg.jboss.logging.provider=log4j作爲JVM運行時參數來完成。

對於SLF4J記錄器,你將需要配置logback.xml文件。補充一點:

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

對於log4j的記錄,您將需要添加下面一行到log4j.properties

log4j.logger.org.hibernate.type=ERROR