4

I have several application-x.properties files which are used for different profiles and each file contains a property with a specific value for each profile. I want to use this property in queries to database as a parameter.

Is it possible to add it using SpEL or something else?

For instance application.properties:

query.parameters.role: ADMIN

possible usage:

@Query(value = "select u from User u where u.role = :#{query.parameters.role}")
Set<User> getAllUsers();

1 Answer 1

6

You might do it by following way:

1.- Find all users by role using Repository Query Keywords

@Repository
public interface UserRepository extends JpaRepository<User, UUID> {

    Set<User> findByRole(String role);
}

2.- Create a method called getAllUsers in UserService and get role value by using @Value:

@Service
public class UserService {

    @Autowired
    private UserRepository repository;

    @Value("${query.parameters.role}")
    private String role;

    public Set<User> getAllUsers() {
        return repository.findByRole(role);
    }
}  

Other way to answer to this question is implement a custom SpEL that is supported by @Query you can take a look this SpEL support in Spring Data JPA

Then you should follow these steps for your case:

1.- Create a ConfigProperties class so that you can read and get the application.properties.

@Configuration
@PropertySource("classpath:application.properties")
@ConfigurationProperties(prefix = "query")
public class ConfigProperties {

    private Parameters parameters;

    // standard getters and setters
}

public class Parameters {

    private String role;

    // standard getters and setters
}

2.- Implement a custom EvaluationContextExtensionSupport and reference to ConfigProperties

public class PropertyEvaluationContextExtension extends EvaluationContextExtensionSupport {

    private final ConfigProperties configProperties;

    public PropertyEvaluationContextExtension(final ConfigProperties configProperties) {
        this.configProperties= configProperties;
    }
    @Override
    public String getExtensionId() {
        return "properties";
    }

    @Override
    public ConfigProperties getRootObject() {
        return this.configProperties;
    }
}

3.- Create a bean in order to be called your custom PropertyEvaluationContextExtension

@Configuration
public class CustomConfig {

    private final ConfigProperties configProperties;

    public CustomConfig(final ConfigProperties configProperties) {
        this.configProperties= configProperties;
    }

    @Bean
    EvaluationContextExtensionSupport propertyExtension() {
        return new PropertyEvaluationContextExtension(configProperties);
    }
} 

4.- Call the query.parameters.role by following format: ?#{query.parameters.role}

@Query(value = "SELECT u FROM User u WHERE u.role = ?#{query.parameters.role}")
Set<User> getAllUsers();
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I knew about this solution, but I'm wondering if it possible to set the property directly in repository.
Ok, so far I know, it is not possible but I will add other way to implement, perhaps you opt to implement it. @kbo
Is there any repo with your solution available?
@EnricoGiurin if you copy and paste what I posted here, so it should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.