Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Partner – Frontegg – expanded (cat = Security)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

Partner – Frontegg – expanded (cat = Spring Security)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

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.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Security bottom

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
Security footer banner
Comments are closed on this article!