Search code examples
javaspringspring-dataspring-data-jdbc

Can I validate custom method inputs in a Spring Data repository?


I want to add a custom method in a Spring Data JDBC repository, this method is supposed to get a string as parameter and I want to check if the string maps to the values of an enum and throw an exception if that's not possible.

This would be the custom method without validation:

@Repository
public interface RunRepository extends ListCrudRepository<Run,Integer> {

  @Query("SELECT * FROM Run WHERE location = :location")
  List<Run> findAllByLocation(String location);

}

My solution was to move the custom method from the RunRepository interface to a new RunRepositoryCustom interface, then write an implementation for it where I validate the value and use a jdbcTemplate service to execute the query if necessary.

While my solution works, I ended up adding quite a few files and writing my own implementation of the custom method.

Is there a way to validate custom method inputs against some custom code while sticking to the declarative Spring Data way with the @Query decorator?

In other words, is there a annotation that allows me to provide a validation function for the method inputs?

Should I move validation to the controllers and let the repository output plain database query results?


Solution

  • In other words, is there a annotation that allows me to provide a validation function for the method inputs?

    No there is no dedicated annotation to do this. But you could (ab)use SpEL for this: Create a method that takes the value to be validate as input and returns it unchanged when valid, otherwise throws an exception and use that method in a SpEL expression in your query.

    There is already a question about how to invoke methods in SpEL expressions.

    Should I move validation to the controllers and let the repository output plain database query results?

    That I think is a good and important question.

    Validation is not something that should done in you persistence layer. Instead you should validate your input and convert it into strong domain objects that can't have invalid state by construction.