I have a simple entity with a requirement that last modified time should be updated on persist.
@Data // Lombok thing
@Entity
@Table(name = "MY_ENTITY")
public class MyEntity {
@Column(name = "LAST_MODIFIED", nullable = false)
private LocalDateTime lastModified;
// irrelevant columns including id omitted
@PrePersist
public void initializeUUID() {
lastModified = LocalDateTime.now();
}
}
I have a requirement to implement a job that queries such entities older than a certain time (let's say a day), modifies its state and persists them. I have a problem with data creation for an unit test that covers such use case.
Although I set manually lastModified
time, the @PrePersist
causes its change regardless the set value.
@Autowired // Spring Boot tests are configured against in-memory H2 database
MyEntityRepository myEntityRepository;
var entity = new MyEntity();
entity.setLastModified(LocalDateTime.now().minusDays(3));
myEntityRepository.entity(entity);
Question: How to prepare pre-persisted data (lastModified
) without drastically modifying the MyEntity
class just for sake of unit tests? A solution using Mockito is welcome.
Note I use Spring Boot + jUnit 5 + Mockito
Things I have tried:
How to mock persisting and Entity with Mockito and jUnit: Mocking persisting the entity is not a way to go because I need the entity to be persisted in H2 for further checks. Moreover, I tried to use spy bean using this trick Spring Boot #7033 with the same result.
Hibernate Tips: How to activate an entity listener for all entities: Adding listener programatically using static nested class configured
@TestConfiguration
for the unit test scope. The thing is not called at all.@TestConfiguration public static class UnitTestConfiguration { // logged as registered @Component public static class MyEntityListener implements PreInsertEventListener { @Override public boolean onPreInsert(PreInsertEvent event) { // not called at all Object entity = event.getEntity(); log.info("HERE {}" + entity); // no log appears // intention to modify the `lastModified` value return true; } }
Dirty way: Create a method-level class extending
MyEntity
with@PrePersist
that "overrides" thelastModified
value. It results inorg.springframework.dao.InvalidDataAccessApiUsageException
. To fix it, such entity relies on the@Inheritance
annotation (JPA : Entity extend with entity), which I don't want to use just for sake of unit tests. The entity must not be extended in the production code.