我正在使用Postgres数据库使用Spring Boot + JPA编写应用程序。我有一个用户实体,正在尝试获取保存和/或修改用户记录时的时间戳。这是行不通的。正在保存的记录的createdDate和lastModifiedDate都为“ null”。
这是Kotlin中的所有相关代码:
@Entity @Table(name = "app_user") @EntityListeners(AuditingEntityListener::class) data class User( @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") val id: UUID? = null, @NotNull @Column(unique = true) val email: String, val name: String, private val password: String, @CreatedDate @Column(name = "created_date", nullable = false, updatable = false) var createdDate: LocalDateTime? = null, @LastModifiedDate @Column(name = "last_modified_date", nullable = false) var lastModifiedDate: LocalDateTime? = null )
我添加日期字段的SQL查询如下所示:
ALTER TABLE app_user ADD COLUMN last_modified_date TIMESTAMP, ADD COLUMN created_date TIMESTAMP;
我也有一个配置类
@Configuration @EnableJpaAuditing(auditorAwareRef = "auditorProvider") class JpaAuditingConfiguration { @Bean fun auditorProvider(): AuditorAware<String> { return AuditorAware { Optional.of(SecurityContextHolder.getContext().authentication.name) } } }
我的测试课:
@Autowired private lateinit var userRepository: UserRepository val user = User( email = "email", name = "name", password = "password" ) @Test fun `it sets the timestamps when a user is created`() { userRepository.save(user) user.let { assertThat(it.createdDate).isNotNull() assertThat(it.lastModifiedDate).isNotNull() } }
更新:
看来问题只发生在测试中。当我在开发环境而不是测试中执行相同的代码来创建用户时,这似乎很好。
测试中是否需要一些其他配置?
更新2
我也尝试使用实体管理器,如下所示:
@Autowired lateinit var entityManager: TestEntityManager
然后在测试中执行以下操作:
entityManager.persist(user) entityManager.flush()
并且
entityManager.persistAndFlush(user)
仍然没有填充时间戳。
在@PrePersist和@PreUpdate阶段调用AuditingEntityListener方法。
@PrePersist
@PreUpdate
这意味着它们将在执行插入或更新SQL语句之前被调用。
在Hibernate文档中了解有关JPA事件的更多信息:https : //docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#events- jpa- callbacks
单元测试
在测试中使用时,您还必须在测试中启用审核
@DataJpaTest @RunWith(SpringRunner.class) @EnableJpaAuditing public class EntityListenerTest {