1. Overview
In this tutorial – we're continuing the ongoing Registration with Spring Security series to setup a scheduled task to purge expired VerificationTokens. During the registration process a VerificationToken is persisted. In this article we will show how to remove these entities.
2. Removing an Expired Token
Recall from the prior article in the series that a verification token has the member expiryDate, representing the expiration timestamp for the token:
@Entity
public class VerificationToken {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String token;
@OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
@JoinColumn(nullable = false, name = "user_id",
foreignKey = @ForeignKey(name="FK_VERIFY_USER"))
private User user;
private Date expiryDate;
...
}
We'll use this expiryDate property to generate a query with Spring Data.
If you're looking for more info on Spring Data JPA, have a look at this article.
2.1. The Delete Operation
To facilitate the token removal we'll add a new method to our VerificationTokenRepository for deleting expired tokens:
public interface VerificationTokenRepository
extends JpaRepository<VerificationToken, Long> {
void deleteByExpiryDateLessThan(Date now);
}
The use of the query keyword LessThan indicates to Spring Data's query creation mechanism that we are only interested in tokens whose expiryDate property is less than the specified time.
Note that because VerificationToken has a @OneToOne association with User marked with FetchType.EAGER, a select is also issued to populate the User entity— even though the signature of deleteByExpiryDateLessThan has the return type void:
select
*
from
VerificationToken verification
where
verification.expiryDate < ?
select
*
from
user_account user
where
user.id=?
delete from
VerificationToken
where
id=?
2.2. The Delete With JPQL
Alternatively, we can create a JPQL query if we do not have a need to load the entities into the persistence context:
public interface VerificationTokenRepository
extends JpaRepository<VerificationToken, Long> {
@Modifying
@Query("delete from VerificationToken t where t.expiryDate <= ?1")
void deleteAllExpiredSince(Date now);
}
And Hibernate will not load the entities into the persistence context:
delete from
VerificationToken
where
expiryDate <= ?
3. Scheduling a Token Purge Task
We now have a query we want to execute periodically; We'll use the scheduling support in Spring and create a method to run our delete logic.
If you're looking for more info on the Spring Job Scheduling framework, have a look at this article.
3.1. Enable Scheduling
To enable the scheduling of tasks we create a new configuration class SpringTaskConfig annotated with @EnableScheduling:
@Configuration
@EnableScheduling
public class SpringTaskConfig {
//
}
3.2. Purge Token Task
In the service layer we call our repository with the current time.
We then annotate the method with @Scheduled to indicate that Spring should execute it periodically:
@Service
@Transactional
public class TokensPurgeTask {
@Autowired
private VerificationTokenRepository tokenRepository;
@Scheduled(cron = "${purge.cron.expression}")
public void purgeExpired() {
Date now = Date.from(Instant.now());
tokenRepository.deleteAllExpiredSince(now);
}
}
3.3. The Schedule
We used a property to hold the value of the crontab settings to avoid recompilation when changed. In the application.properties we assign the value:
# 5am every day
purge.cron.expression=0 0 5 * * ?
4. Conclusion
In this article we solved the removal of VerificationTokens using Spring Data JPA.
We demonstrated query creation using a property expression to find all tokens having an expiration date less than a specified time. And we created a task to invoke this clean logic at runtime – and registered it with the Spring Job Scheduling framework to be executed periodically.
The implementation of this Registration with Spring Security tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.
Course – LS (cat=Spring)
Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:
>> THE COURSE
Course – LSS (cat=Security/Spring Security)
I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security 5:
>> CHECK OUT THE COURSE
res – Security (video) (cat=Security/Spring Security)