Spring Boot JPA@CreatedDate @LastModifiedDate n'est pas renseigné lors de l'enregistrement de l'objet
J'écris une application avec Spring Boot + JPA, en utilisant une base de données Postgres. J'ai une entité utilisateur et j'essaie d'obtenir un horodatage lorsque l'enregistrement de l'utilisateur est enregistré et/ou modifié. Cela ne fonctionne pas. L'enregistrement en cours de sauvegarde a "null" pour les deux createdDate et lastModifiedDate.
Voici tout le code pertinent dans 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
)
Mes requêtes SQL pour ajouter les champs de date ressemblent à ceci :
ALTER TABLE app_user
ADD COLUMN last_modified_date TIMESTAMP,
ADD COLUMN created_date TIMESTAMP;
J'ai aussi une classe de configuration
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
class JpaAuditingConfiguration {
@Bean
fun auditorProvider(): AuditorAware<String> {
return AuditorAware { Optional.of(SecurityContextHolder.getContext().authentication.name) }
}
}
Et ma classe de test:
@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()
}
}
METTRE À JOUR:
Il semble que le problème ne se produise que dans les tests. Il semble bien que j'exécute le même code pour créer un utilisateur dans l'environnement de développement et non dans les tests.
Ai-je besoin d'une configuration supplémentaire dans les tests ?
MISE À JOUR 2
J'ai aussi essayé d'utiliser le gestionnaire d'entités comme ceci:
@Autowired
lateinit var entityManager: TestEntityManager
Ensuite, dans le test, faites:
entityManager.persist(user)
entityManager.flush()
Et aussi
entityManager.persistAndFlush(user)
Ne remplit toujours pas les horodatages.
Solution du problème
Les méthodes AuditingEntityListener sont appelées dans les phases @PrePersist
et.@PreUpdate
Cela signifie qu'ils sont appelés juste avant l'exécution des instructions SQL d'insertion ou de mise à jour.
En savoir plus sur les événements JPA dans la documentation Hibernate :
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#events-jpa-callbacks
Tests unitaires
Lors de l'utilisation dans les tests, vous devez également activer l'audit sur le test
@DataJpaTest
@RunWith(SpringRunner.class)
@EnableJpaAuditing
public class EntityListenerTest {
Commentaires
Enregistrer un commentaire