Hibernate logging in Spring application on JBoss 7

2019-05-25 06:03发布

问题:

I have Spring MVC application integrated with Hibernate.

I'm trying to log jdbc SQL statement parameters using Log4j but it doesn't work. It seems like my log4j.properties configuration file does not make any changes. Here is project config:

I'm using Maven, Eclipse and log4j.properties file is at the top of the projects source folder (so as I understand in the classpath).

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>TestProject</groupId>
  <artifactId>TestProject</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <org.hibernate.version>3.6.0.Final</org.hibernate.version>
    <org.springframework.version>3.1.2.RELEASE</org.springframework.version>
    <org.apache.tiles.version>2.2.2</org.apache.tiles.version>
    <slf4j-log4j12.version>1.7.0</slf4j-log4j12.version>
  </properties>
  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${org.springframework.version}</version>
        <scope>runtime</scope>
        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${org.hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.2.8</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.16.1-GA</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-extras</artifactId>
        <version>${org.apache.tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
  </dependencies>
</project>

log4j.properties

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{ABSOLUTE} %5p %c{1}:%L - %m%n

log4j.rootLogger=ERROR, stdout

log4j.logger.main.mvc.model.hibernate=DEBUG

log4j.logger.org.hibernate=INFO
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

回答1:

OK. So I finally got it working!

All these troubles were caused by JBoss AS 7.1.

So here is how to set up slf4j+log4j logging on Spring MVC application that is run on JBoss AS 7.1:

  1. There are built-in JBoss modules that has to be turneda off so - add jboss-deployment-structure.xml to your META-INF/ directory
  2. You have to have these libraries in classpath: log4j.jar, slf4j-api.jar, slf4j-log4j12.jar, jcl-over-sfl4j.jar. Spring's default common-logging.jar has to be excluded from classpath.
  3. You have to have log4j.properties or log4j.xml file in classpath.

These files gave me control over logs and I achieved my goal - logging Hibernate SQL statement parameters.

jboss-deployment-structure.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <exclusions>
            <module name="org.apache.log4j" />
            <module name="org.slf4j" />
            <module name="org.slf4j.impl" />
        </exclusions>
    </deployment>
</jboss-deployment-structure> 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>bladositto</groupId>
  <artifactId>TestLogging</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <org.hibernate.version>3.6.0.Final</org.hibernate.version>
    <org.springframework.version>3.1.2.RELEASE</org.springframework.version>
    <org.apache.tiles.version>2.2.2</org.apache.tiles.version>
    <slf4j-log4j12.version>1.7.0</slf4j-log4j12.version>
  </properties>
  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${org.springframework.version}</version>
        <scope>runtime</scope>
        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${org.hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.2.8</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.16.1-GA</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-extras</artifactId>
        <version>${org.apache.tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${slf4j-log4j12.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
  </dependencies>
</project>

log4j.properties

log4j.rootLogger=INFO, A1, R

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Target=System.out
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE


回答2:

You are using this in your log4j config

org.apache.commons.digester.Digester=INFO
org.hibernate=INFO
org.springframework.orm=DEBUG,stdout

Whereas it should be

log4j.logger.org.apache.commons.digester.Digester=INFO
log4j.logger.org.hibernate=INFO
log4j.logger.org.springframework.orm=DEBUG,stdout


回答3:

Try with the following in your hibernate.cfg.xml or in your persistence.xml:

<property name="hibernate.show_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>

Plus the following inside your log4j.properties:

log4j.rootLogger=INFO,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=INFO
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %-5p %x - %m%n

org.apache.commons.digester.Digester=INFO
org.hibernate=INFO
org.springframework.orm=DEBUG,stdout

I have no doubt you will have logs if you put these two files in the classpath of your webapp.

With Maven, you should put these files inside the folder src/main/resources. They will be packaged inside the resulting target folder you will get if you do a 'mvn clean package`.

To declare a slf4j logger, you should do this way:

public class User {
    public static final Logger logger = LoggerFactory.getLogger(User.class);

    //fields getters and setters...

    public User() {

    }

    public User(DTO userDTO) {
        this.username = userDTO.username;
        // etc.
        logger.debug("your user was initialized with the DTO, see this.toString()=?", this.toString());
    } 


    //etc. some other methods, if any

    //toString()
    public String toString() {
        //return a String representation of an User object.
    }
}

And to limit a log level for a specific appender, you should use:

log4j.logger.appenderName.packageName.className=LEVEL

Note you are currently using:

log4j.logger.packageName.className=LEVEL

Good luck!