Welcome to Hibernate Log4j Logging example. Hibernate 4 uses JBoss logging rather than slf4j in older hibernate versions. Today we will look into how to configure log4j in a hibernate application.
欢迎使用Hibernate Log4j日志记录示例。 Hibernate 4在较早的hibernate版本中使用JBoss日志记录而不是slf4j。 今天,我们将研究如何在Hibernate应用程序中配置log4j。
Create a maven project in the Eclipse or your favorite IDE, final project structure will look like below image.
在Eclipse或您最喜欢的IDE中创建一个maven项目,最终项目结构如下图所示。
Let’s look into each of the components one by one.
让我们逐一研究每个组件。
We need hibernate-core, mysql driver and log4j dependencies in our project, our final pom.xml file looks like below.
我们的项目中需要hibernate-core,mysql驱动程序和log4j依赖项,最终的pom.xml文件如下所示。
4.0.0
com.journaldev.hibernate
HibernateLog4JExample
0.0.1-SNAPSHOT
org.hibernate
hibernate-core
4.3.5.Final
log4j
log4j
1.2.16
mysql
mysql-connector-java
5.0.5
I am using XML based log4j configuration, we can also use property file based configuration.
我正在使用基于XML的log4j配置,我们也可以使用基于属性文件的配置。
log4j.xml
log4j.xml
This file needs to be placed at the root folder, so that our main class can access it. Notice the location of log4j log files, our application generated logs will go into project.log whereas hibernate logs will go into system.log file.
该文件需要放在根文件夹中,以便我们的主类可以访问它。 注意log4j日志文件的位置,我们的应用程序生成的日志将进入project.log,而Hibernate日志将进入system.log文件。
Our hibernate configuration xml looks like below.
我们的Hibernate配置xml如下所示。
hibernate.cfg.xml
hibernate.cfg.xml
com.mysql.jdbc.Driver
pankaj123
jdbc:mysql://localhost/TestDB
pankaj
org.hibernate.dialect.MySQLDialect
thread
true
package com.journaldev.hibernate.util;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Logger logger = Logger.getLogger(HibernateUtil.class);
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
logger.info("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
logger.info("Hibernate serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
logger.error("Initial SessionFactory creation failed." + ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
}
Notice that I am using log4j Logger for logging purpose, since this class is part of our application, the logs should go into project.log file.
注意,我正在使用log4j Logger进行日志记录,因为此类是我们应用程序的一部分,因此日志应放入project.log文件中。
We have two model classes – Employee and Address. I am using the same database setup as in HQL Example, so you can check that tutorial to look into database setup and model classes. Both of these classes are simple java beans with hibernate annotation based mapping.
我们有两个模型类-雇员和地址。 我正在使用与HQL Example中相同的数据库设置,因此您可以检查该教程以研究数据库设置和模型类。 这两个类都是简单的Java Bean,具有基于Hibernate注释的映射 。
Our main class looks like below.
我们的主要班级如下所示。
package com.journaldev.hibernate.main;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateLog4jExample {
static{
System.out.println("Before log4j configuration");
DOMConfigurator.configure("log4j.xml");
System.out.println("After log4j configuration");
}
private static Logger logger = Logger.getLogger(HibernateLog4jExample.class);
@SuppressWarnings("unchecked")
public static void main(String[] args) {
//Prep work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
//Get All Employees
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Employee");
List empList = query.list();
for(Employee emp : empList){
logger.info("List of Employees::"+emp.getId()+","+emp.getAddress().getCity());
}
tx.commit();
sessionFactory.close();
logger.info("DONE");
}
}
Notice that we don’t need to do anything to plugin log4j logging. Obviously we would need to configure it first before using it, that’s why I am using static block to make sure log4j is configured before we start using it. I am using org.apache.log4j.xml.DOMConfigurator
because our log4j configuration is XML based, if you have property file based configuration, you should use org.apache.log4j.PropertyConfigurator
class.
注意,我们不需要对插件log4j日志进行任何操作。 显然,在使用它之前,我们需要先对其进行配置,这就是为什么我在开始使用它之前使用静态块来确保已配置log4j的原因。 我使用org.apache.log4j.xml.DOMConfigurator
因为我们的log4j配置基于XML,如果您具有基于属性文件的配置,则应使用org.apache.log4j.PropertyConfigurator
类。
Now when we execute above program, we get following data in log4j files.
现在,当我们执行上述程序时,将在log4j文件中获取以下数据。
project.log
project.log
2014-06-05 20:00:11,868 -0700 [main] INFO (HibernateUtil.java:20) - Hibernate Configuration loaded
2014-06-05 20:00:11,936 -0700 [main] INFO (HibernateUtil.java:23) - Hibernate serviceRegistry created
2014-06-05 20:00:12,698 -0700 [main] INFO (HibernateLog4jExample.java:37) - List of Employees::1,San Jose
2014-06-05 20:00:12,698 -0700 [main] INFO (HibernateLog4jExample.java:37) - List of Employees::2,Santa Clara
2014-06-05 20:00:12,698 -0700 [main] INFO (HibernateLog4jExample.java:37) - List of Employees::3,Bangalore
2014-06-05 20:00:12,698 -0700 [main] INFO (HibernateLog4jExample.java:37) - List of Employees::4,New Delhi
2014-06-05 20:00:12,712 -0700 [main] INFO (HibernateLog4jExample.java:42) - DONE
Notice that above log file contains only entries generated by our program, this way we can separate our application logs from hibernate logs.
注意,上面的日志文件仅包含由程序生成的条目,这样我们就可以将应用程序日志与Hibernate日志分开。
system.log
system.log
2014-06-05 22:49:58,415 -0700 [main] INFO (JavaReflectionManager.java:66) - HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
2014-06-05 22:49:58,423 -0700 [main] INFO (Version.java:54) - HHH000412: Hibernate Core {4.3.5.Final}
2014-06-05 22:49:58,426 -0700 [main] INFO (Environment.java:239) - HHH000206: hibernate.properties not found
2014-06-05 22:49:58,427 -0700 [main] INFO (Environment.java:346) - HHH000021: Bytecode provider name : javassist
2014-06-05 22:49:58,446 -0700 [main] INFO (Configuration.java:2073) - HHH000043: Configuring from resource: hibernate.cfg.xml
2014-06-05 22:49:58,447 -0700 [main] INFO (Configuration.java:2092) - HHH000040: Configuration resource: hibernate.cfg.xml
2014-06-05 22:49:58,491 -0700 [main] INFO (Configuration.java:2214) - HHH000041: Configured SessionFactory: null
2014-06-05 22:49:58,557 -0700 [main] WARN (DriverManagerConnectionProviderImpl.java:93) - HHH000402: Using Hibernate built-in connection pool (not for production use!)
2014-06-05 22:49:58,560 -0700 [main] INFO (DriverManagerConnectionProviderImpl.java:166) - HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
2014-06-05 22:49:58,561 -0700 [main] INFO (DriverManagerConnectionProviderImpl.java:175) - HHH000046: Connection properties: {user=pankaj, password=****}
2014-06-05 22:49:58,561 -0700 [main] INFO (DriverManagerConnectionProviderImpl.java:180) - HHH000006: Autocommit mode: false
2014-06-05 22:49:58,562 -0700 [main] INFO (DriverManagerConnectionProviderImpl.java:102) - HHH000115: Hibernate connection pool size: 20 (min=1)
2014-06-05 22:49:58,699 -0700 [main] INFO (Dialect.java:145) - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2014-06-05 22:49:58,706 -0700 [main] INFO (LobCreatorBuilder.java:97) - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
2014-06-05 22:49:58,828 -0700 [main] INFO (TransactionFactoryInitiator.java:62) - HHH000399: Using default transaction strategy (direct JDBC transactions)
2014-06-05 22:49:58,832 -0700 [main] INFO (ASTQueryTranslatorFactory.java:47) - HHH000397: Using ASTQueryTranslatorFactory
2014-06-05 22:49:59,207 -0700 [main] INFO (DriverManagerConnectionProviderImpl.java:281) - HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]
Since our hibernate logs level is set to INFO mode, there are not many logs. If you will change it to debug, even this simple program generates more than 1400 lines of log. Analyzing these logs are sometime crucible in understanding how hibernate works internally and to debug issues related to hibernate.
由于我们的Hibernate日志级别设置为INFO模式,因此日志不多。 如果您将其更改为调试,那么即使这个简单的程序也会生成1400多行日志。 有时,分析这些日志对于了解Hibernate在内部的工作方式以及调试与Hibernate有关的问题非常重要。
Also, we got following logs generated in console.
另外,我们在控制台中生成了以下日志。
Before log4j configuration
After log4j configuration
Hibernate: select employee0_.emp_id as emp_id1_1_, employee0_.emp_name as emp_name2_1_, employee0_.emp_salary as emp_sala3_1_ from EMPLOYEE employee0_
Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
Notice that Hibernate is printing SQL queries to the console log, this is happening from org.hibernate.engine.jdbc.spi.SqlStatementLogger
class logStatement
method, code snippet is:
注意,Hibernate正在将SQL查询打印到控制台日志,这是从org.hibernate.engine.jdbc.spi.SqlStatementLogger
类logStatement
方法发生的,代码片段为:
if (this.logToStdout)
System.out.println("Hibernate: " + statement);
This is controlled by hibernate.show_sql
property in hibernate.cfg.xml file. Actually if you are using log4j, then you should turn it off because they will also be part of log files if logging level is set to DEBUG mode. Having it in log files make more sense that getting it printed on console.
这由hibernate.cfg.xml文件中的hibernate.show_sql
属性控制。 实际上,如果您正在使用log4j,则应将其关闭,因为如果将日志记录级别设置为DEBUG模式,它们也将成为日志文件的一部分。 将其保存在日志文件中比在控制台上打印更有意义。
That’s all for hibernate log4j logging example, as you can see it’s very easy to plugin and all we need is to configure log4j properly. You can download the project from below link.
这就是Hibernatelog4j日志记录示例的全部内容,您可以看到它非常容易插入,而我们所需要做的就是正确配置log4j。 您可以从下面的链接下载项目。
翻译自: https://www.journaldev.com/2984/hibernate-log4j-logging