How to enable JPA auditing with SpringBootTest?

蓝咒 提交于 2020-07-10 07:58:23

问题


I want to write integration tests for my RestAPI endpoints, and I'm struggling with @EnableJpaAuditing. I want some of my entities to be audited by Spring, so I've created the following configuration class:

@Configuration
@EnableJpaAuditing
public class PersistenceAuditConfiguration {

}

Which I import into my main application config:

@ServletComponentScan
@SpringBootApplication
@Import(PersistenceAuditConfiguration.class)
public class TMTWebApplication {

    public static void main(String[] args)  {
        SpringApplication.run(TMTWebApplication.class, args);
    }
}

Also, I have an abstract base class for all entities that I want to be audited:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public abstract class AuditableEntity extends EpicPojo implements Serializable {

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
@CreatedDate
private Date createdAt;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at", nullable = false)
@LastModifiedDate
private Date updatedAt;

    //...and so on

}

In my application.yml, I have set the following properties:

spring:
    datasource:
        url: jdbc:postgresql://localhost:5432/tmt
        username: whoever
        password: whatever
        driver-class-name: org.postgresql.Driver
    flyway:
        baselineOnMigrate: true
        locations: classpath:db/migration
    jpa:
        hibernate:
            ddl-auto: update
        generate-ddl: true
        properties:
            hibernate:
                dialect: org.hibernate.dialect.PostgreSQL10Dialect
                jdbc:
                    lob:
                        non_contextual_creation: true

This way, I can omit the auditing fields (columns) in my Flyway migration scripts. When I start the application normally on an empty database, the auditing columns created_at and updated_at are being created for every entity that inherits from AuditableEntity.

Now, I want to run my integration test using the @SpringBootTest annotation, so I am expecting the whole application context to be started pretty much the same way. Unfortunately, this is not the case. I am using Zonky's embedded Postgres for tests since I have some JSONB datatypes. Setting it up worked seamlessly, but unfortunately the auditing fields aren't created. My test class looks like this:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureEmbeddedDatabase
@FlywayTest
@Import(PersistenceAuditConfiguration.class)
public class AuthController_IntegrationTest {

    //... testy-testy, test, test

}

The first test will insert (register) a new user to my audited users table and return it, but it fails due to the following exception:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is 
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; 
nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

[stack trace omitted]

Caused by: org.postgresql.util.PSQLException: ERROR: column roleentity0_.created_at does not exist

I've found a lot of similar issues, but most dealt with @DataJpaTest and not @SpringBootTest (at this point I don't want to test different layers separately). According to different threads and issues I could find, I've also tried the following:

  • @EnableJpaAuditing directly on TMTWebApplication config class, which was the first and original way prior to writing integration tests.

  • @EnableJPAAudidting directly on my test class, which led to a BeanDefinitionOverrideException. After I reluctantly allowed bean overriding, I ran into the above exception again (created_at does not exist).

I can see that there are issues from this and this thread on Github, but I don't yet understand the underlying design of Spring for this particular configuration, and the documentation didn't really help either. Please note: I've asked a similar question to this issue yesterday, but I deleted it. I suspected that it had something to do with Zonky's embedded Postgres instance not understanding the application properties, but I guess that was wrong, so I had to rephrase it to focus on Spring only. I guess, I am missing the forest for all the trees around here, so if someone could point me to the right tree, I'd highly appreciate it. Thanks in advance!

来源:https://stackoverflow.com/questions/62211613/how-to-enable-jpa-auditing-with-springboottest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!