Java – activate SQL statements using hibernate and spring data JPA

I have a spring data JPA repository that uses hibernate as a provider I want to record SQL statements, but I can't I've tried various solutions:

>Set showsql to true in my hibernate JPA vendoradapter > log4j logger. org. hibernate. SQL = debug added to my log4j Properties file (it is worth mentioning that log4j.logger.org.hibernate = info does add some log information, but log4j.logger.org.hibernate.sql = debug does not)

This is my class and configuration file:

DatabaseConfiguration. java

/**
 * Database configuration
 *
 * @author dupirefr
 */
@Configuration
@Import({BaseConfiguration.class,DatabaseProperties.class})
@EnableJpaRepositories(basePackages = DatabaseConfiguration.REPOSITORIES_PACKAGE)
public class DatabaseConfiguration {

    /*
     * Constants
     */
    public static final String MODEL_PACKAGE = "be.dupirefr.examples.spring.batch.simple.model";
    public static final String REPOSITORIES_PACKAGE = "be.dupirefr.examples.spring.batch.simple.repositories";

    /*
     * Beans
     */
    @Bean
    public DataSource dataSource(DatabaseProperties properties) {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(properties.url);
        dataSource.setUsername(properties.username);
        dataSource.setPassword(properties.password);
        dataSource.setDriverClassName(properties.driverClassName);

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerfactorybean entityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerfactorybean entityManagerfactorybean = new LocalContainerEntityManagerfactorybean();
        entityManagerfactorybean.setDataSource(dataSource);
        entityManagerfactorybean.setPackagesToScan(MODEL_PACKAGE);
        entityManagerfactorybean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return entityManagerfactorybean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

database. properties

# Data source
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=admin
spring.datasource.password=admin
spring.datasource.driver-class-name=org.h2.Driver

DatabaseProperties. java

/**
 * Database properties
 *
 * @author dupirefr
 */
@Configuration
@PropertySource("classpath:be/dupirefr/examples/spring/batch/simple/config/database/database.properties")
public class DatabaseProperties {

    /*
     * Fields
     */
    @Value("${spring.datasource.url}")
    public String url;

    @Value("${spring.datasource.username}")
    public String username;

    @Value("${spring.datasource.password}")
    public String password;

    @Value("${spring.datasource.driver-class-name}")
    public String driverClassName;

}

EmployerRepository. java

/**
 * {@link Employer}'s repository
 *
 * @author dupirefr
 */
@Repository
public interface EmployerRepository extends JpaRepository<Employer,Long> {

}

EmployerRepositoryIT. java

/**
 * {@link EmployerRepository}'s integration test
 *
 * @author dupirefr
 */
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = DatabaseConfiguration.class)
@Transactional
public class EmployerRepositoryIT {

    /*
     * Constants
     */
    public static final Employer GOOGLE = new Employer(1L,"Google");
    public static final Employer MICROSOFT = new Employer(2L,"Microsoft");
    public static final Employer APPLE = new Employer(3L,"Apple");

    /*
     * Fields
     */
    @Autowired
    private EmployerRepository repository;

    @Autowired
    private EntityManager entityManager;

    /*
     * Setups
     */
    @Before
    public void setUp() {
        entityManager.persist(GOOGLE);
        entityManager.persist(MICROSOFT);
    }

    /*
     * Tests
     */
    @Test
    public void findById_Exists() {
        assertEquals(GOOGLE,repository.findById(GOOGLE.getId()).get());
        assertEquals(MICROSOFT,repository.findById(MICROSOFT.getId()).get());
    }

    @Test
    public void findById_NotExists() {
        assertFalse(repository.findById(Long.MAX_VALUE).isPresent());
    }

    @Test
    public void findAll() {
        assertEquals(Arrays.asList(GOOGLE,MICROSOFT),repository.findAll());
    }

    @Test
    public void save() {
        repository.save(APPLE);
        assertEquals(APPLE,entityManager.find(Employer.class,APPLE.getId()));
    }

    @Test
    public void delete() {
        repository.delete(MICROSOFT);
        assertNull(entityManager.find(Employer.class,MICROSOFT.getId()));
    }

}

log4j. properties

# Appenders
## Console
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

# Loggers
## Root
log4j.rootLogger=INFO,stdout

## Hibernate
### Generic
log4j.logger.org.hibernate=INFO
### sql statements
log4j.logger.org.hibernate.sql=DEBUG

Why didn't the previous solution work? Is there any incompatibility between spring data JPA and Hibernate SQL log configuration?

Editor: I tried two solutions in the comments, but none worked I also tried to change the database I was using (H2 for hsql) or specify the hibernate dialect, but it didn't work In fact, when using spring, some databases will automatically find hibernate dialect

Edit 2: I tried to change the logging level of rootlogger to trace I also try to specify the appender threshold explicitly Finally, I tried to add jpaproperties using showsql = true, but none of them could be implemented I think there are some very obvious things to do because I lack the complete situation of unlocking: –/

Edit 3: directly call the recorder. For example, the following test is really effective I began to wonder if there were typing errors or something that prevented hibernate from using the recorder

@Test
public void delete() {
    LoggerFactory.getLogger("org.hibernate.sql").debug("delete()");
    repository.delete(MICROSOFT);
    assertNull(entityManager.find(Employer.class,MICROSOFT.getId()));
}

The following are the generated logs:

10:33:45,158  INFO DefaultTestContextBootstrapper:257 - Loaded default TestExecutionListener class names from location [Meta-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener,org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener,org.springframework.test.context.support.DependencyInjectionTestExecutionListener,org.springframework.test.context.support.DirtiesContextTestExecutionListener,org.springframework.test.context.transaction.TransactionalTestExecutionListener,org.springframework.test.context.jdbc.sqlScriptsTestExecutionListener]
10:33:45,183  INFO DefaultTestContextBootstrapper:206 - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
10:33:45,185  INFO DefaultTestContextBootstrapper:184 - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@1f28c152,org.springframework.test.context.support.DependencyInjectionTestExecutionListener@7d907bac,org.springframework.test.context.support.DirtiesContextTestExecutionListener@7791a895,org.springframework.test.context.transaction.TransactionalTestExecutionListener@3a5ed7a6,org.springframework.test.context.jdbc.sqlScriptsTestExecutionListener@6325a3ee]10:33:45,376  INFO GenericApplicationContext:589 - Refreshing org.springframework.context.support.GenericApplicationContext@4493d195: startup date [Sun Jan 14 10:33:45 CET 2018]; root of context hierarchy
10:33:46,187  WARN ConfigurationClassEnhancer:353 - @Bean method BaseConfiguration.propertySourcesPlaceholderConfigurer is non-static and returns an object assignable to Spring's beanfactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired,@Resource and @postconstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
10:33:46,448  INFO DriverManagerDataSource:133 - Loaded JDBC driver: org.h2.Driver
10:33:46,743  INFO LocalContainerEntityManagerfactorybean:361 - Building JPA container EntityManagerFactory for persistence unit 'default'
10:33:46,798  INFO LogHelper:31 - HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
10:33:46,922  INFO Version:45 - HHH000412: Hibernate Core {5.2.12.Final}
10:33:46,924  INFO Environment:213 - HHH000206: hibernate.properties not found
10:33:46,979  INFO Version:66 - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
10:33:47,318  INFO Dialect:157 - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
10:33:48,472  INFO LocalContainerEntityManagerfactorybean:393 - Initialized JPA EntityManagerFactory for persistence unit 'default'
10:33:49,422  INFO TransactionContext:105 - Began transaction (1) for test context [DefaultTestContext@2e3f79a2 testClass = EmployerRepositoryIT,testInstance = be.dupirefr.examples.spring.batch.simple.repositories.EmployerRepositoryIT@1460c81d,testMethod = delete@EmployerRepositoryIT,testException = [null],mergedContextConfiguration = [MergedContextConfiguration@38b5f25 testClass = EmployerRepositoryIT,locations = '{}',classes = '{class be.dupirefr.examples.spring.batch.simple.config.database.DatabaseConfiguration}',contextInitializerClasses = '[]',activeProfiles = '{}',propertySourceLocations = '{}',propertySourceProperties = '{}',contextCustomizers = set[[empty]],contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader',parent = [null]],attributes = map[[empty]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@5b22b970]; rollback [true]
10:33:49,468 DEBUG sql:83 - delete()
10:33:49,512  INFO TransactionContext:137 - Rolled back transaction for test context [DefaultTestContext@2e3f79a2 testClass = EmployerRepositoryIT,attributes = map[[empty]]].
10:33:49,516  INFO GenericApplicationContext:989 - Closing org.springframework.context.support.GenericApplicationContext@4493d195: startup date [Sun Jan 14 10:33:45 CET 2018]; root of context hierarchy
10:33:49,519  INFO LocalContainerEntityManagerfactorybean:571 - Closing JPA EntityManagerFactory for persistence unit 'default'

Editor 3: I finally figured out what happened I noticed that in the failed test, the SQL query was issued in the log By adjusting my log4j properties, I see that they come from hibernate logger, as expected

But the successful operation is not to publish the log That's because they didn't reach the database Everything happens in the entity manager, so you don't need SQL Now I know there is a problem with my H2 database. I need to find out

Solution

Since viewing the code you provided doesn't seem to cut it, I'll try using some instructions on how to debug it

>Keep the changes I gave in the first answer. > Make sure that the properties file you display is actually the control logger configuration For this change, for example, the output format and check that it affects the output as expected. > Find relevant logging statements in hibernate Set a breakpoint there Debug until the location where the log statement is discarded is found Compare the data structures involved in the configuration to see what's wrong

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>