Hibernate JPA EntityManager创建额外的log4j appender?

时间:2012-05-06 15:45:24

标签: hibernate logging log4j entitymanager

我编写了一个简单的控制台应用程序,它使用JPA连接到MySQL数据库。数据的实际读取/写入工作正常,但是日志记录似乎搞砸了。我创建的每个EntityManager实例似乎都将自己的log4j appender添加到控制台。所以,因为我的应用程序中有三个EntityManager实例,除了我想要的“真实”控制台输出行之外,我在控制台输出中还有三行。这是一个例子。第一行来自我的“真正的”appender,其他三个似乎来自EntityManager的appender:

08:31:58,970 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:169 - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 

这是我的log4j配置:

log4j.rootCategory=WARN, mylog

log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout
log4j.appender.mylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

log4j.category.foobar=DEBUG

我希望能够关闭此行为并获取我想要的控制台行。我似乎无法“破解代码”如何做到这一点 - 任何帮助将不胜感激......

其他信息:这里似乎有两件事情。第一个是log4j appender additivity设置,默认情况下为true。重新阅读稀疏的log4j文档(http://logging.apache.org/log4j/1.2/manual.html)我遇到了这个:

  

给定记录器的每个已启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender。

没有提及的是,无论层次结构中记录器的设置如何,它显然都会这样做。

这意味着,或者在我的情况下似乎意味着,虽然我的根记录器设置为WARN,但是Hibernate类附加到它的appender仍然被DEBUG级别的消息使用。这与我期望发生的情况相反。我不确定这是否代表了Hibernate 4.0.1 JPA实现中的错误,或者只是缺少log4j的文档,或者是log4j和slf4j之间的故障(由Hibernate使用)。

第二件事是每次创建一个EntityManager对象时,它似乎都会在log4j日志树中添加一个appender,所以如果你有多个EntityManagers,你会得到多个日志消息。我很确定这是Hibernate日志记录中的一个错误。

仍在寻找一个解释或这个“可加性”如何在log4j实践中起作用的一个例子 - 它似乎与我对有限文档的期望相反。也就是说,appender似乎是通过DOWN日志记录树而不是记录传递UP的事件。

这是我迄今为止(修改过的)log4j属性文件的内容,它似乎正在运行:

log4j.rootCategory=WARN, mylog

# logger "root" logs at WARN level to appender "mylog"
log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout

# Logger "foobar" logs at DEBUG level to appender "bootylog"
log4j.category.foobar=DEBUG, bootylog

log4j.appender.bootylog=org.apache.log4j.ConsoleAppender
log4j.appender.bootylog.layout=org.apache.log4j.PatternLayout
log4j.appender.bootylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

# additivity is off
log4j.additivity.foobar=false
log4j.additivity.org.hibernate=false

这给了我以下输出,这正是我想要的:

11:15:43,622 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:152 - geoDataItemDao.create took 5 milliseconds 
11:15:43,624 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:166 - geoEntityDao.getByCompositeKey took 2 milliseconds 
11:15:43,626 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:159 - dataEntityDao.getDataEntityByFieldCode took 1 milliseconds 

最后,我强烈建议任何遇到log4j问题的人在运行app时打开此命令行选项:

-Dlog4j.debug 

2 个答案:

答案 0 :(得分:0)

作为answered elsewhere,尝试在log4j属性中更改hibernate的日志记录级别

e.g。

log4j.logger.org.hibernate=info

答案 1 :(得分:0)

看来这里有两件事情。第一个是log4j appender additivity设置,默认情况下为true。重新阅读稀疏的log4j文档(http://logging.apache.org/log4j/1.2/manual.html)我遇到了这个:

  

给定记录器的每个已启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender。

没有提及的是,无论层次结构中记录器的设置如何,它显然都会这样做。

这意味着,或者在我的情况下似乎意味着,虽然我的根记录器设置为WARN,但是Hibernate类附加到它的appender仍然被DEBUG级别的消息使用。这与我期望发生的情况相反。我不确定这是否代表了Hibernate 4.0.1 JPA实现中的错误,或者只是缺少log4j的文档,或者是log4j和slf4j之间的故障(由Hibernate使用)。

第二件事是每次创建一个EntityManager对象时,它似乎都会在log4j日志树中添加一个appender,所以如果你有多个EntityManagers,你会得到多个日志消息。我很确定这是Hibernate日志记录中的一个错误。

仍在寻找一个解释或这个“可加性”如何在log4j实践中起作用的一个例子 - 它似乎与我对有限文档的期望相反。也就是说,appender似乎是通过DOWN日志记录树而不是记录传递UP的事件。

这是我迄今为止(修改过的)log4j属性文件的内容,它似乎正在运行:

log4j.rootCategory=WARN, mylog

# logger "root" logs at WARN level to appender "mylog"
log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout

# Logger "foobar" logs at DEBUG level to appender "bootylog"
log4j.category.foobar=DEBUG, bootylog

log4j.appender.bootylog=org.apache.log4j.ConsoleAppender
log4j.appender.bootylog.layout=org.apache.log4j.PatternLayout
log4j.appender.bootylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

# additivity is off
log4j.additivity.foobar=false
log4j.additivity.org.hibernate=false

这给了我以下输出,这正是我想要的:

11:15:43,622 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:152 - geoDataItemDao.create took 5 milliseconds 
11:15:43,624 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:166 - geoEntityDao.getByCompositeKey took 2 milliseconds 
11:15:43,626 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:159 - dataEntityDao.getDataEntityByFieldCode took 1 milliseconds 

最后,我强烈建议任何遇到log4j问题的人在运行app时打开此命令行选项:

-Dlog4j.debug