web-dev-qa-db-fra.com

Existe-t-il un moyen d'utiliser des constantes dans la valeur d'annotation Spring Data @Query?

Je ne veux pas coder en dur les valeurs constantes, je préfère les spécifier via une variable de référence.

Par exemple, plutôt que d'écrire la requête suivante:

@Query(value = "SELECT u FROM UserModel u WHERE u.status = 1")

..Je voudrais extraire la valeur codée en dur "1" et écrire quelque chose comme:

@Query(value = "SELECT u FROM UserModel u WHERE u.status = UserModel.STATUS_ACTIVE")  //doesn't compile

Existe-t-il un moyen de spécifier des constantes comme dans le deuxième exemple dans les requêtes Spring-Data?

29
Roman

Vous devez utiliser un nom de classe complet comme celui-ci:

@Query("SELECT u FROM UserModel u WHERE u.status = com.example.package.UserModel.STATUS_ACTIVE")

Cependant, la mauvaise chose à ce sujet est qu’un IDE ne reconnaîtrait pas cela comme une utilisation de la classe UserModel. Le seul avantage est que vous pouvez conserver la valeur en un seul endroit, ce qui est suffisant pour la plupart des le temps.

24
Cleankod

Je recommanderais de créer un Enum et un champ de cette énumération sur l'entité.

public enum UserModelStatus{
     ACTIVE, INACTIVE
}

public UserModel{

    /* Other fields ommitted */

    @Enumerated(EnumType.STRING)
    private UserModelStatus status;

    /* Get/Set Method */
}

Créez ensuite votre méthode de référentiel:

@Repository
public interface UserModelRepository extends JpaRepository<UserModel, Long>{

    public List<UserModel> findByStatus(UserModelStatus status);

}

En utilisant Spring Data, vous n'aurez même pas besoin d'écrire JPQL, il suffit d'appeler la méthode comme:

   @Autowired
   UserModelRepository userModelRepository;

   public void someMethod(){
       List<UserModel> userModels = userModelRepository.findByStatus(UserModelStatus.ACTIVE);
   }
10
Kevin Bowersox

Utilisez comme suit:

Dans l'interface du référentiel, définissez une constante comme suit:

public static final String USER_QUERY = "SELECT u FROM UserModel u WHERE u.status = " + UserModel.STATUS_ACTIVE;

Vous pouvez maintenant utiliser

@Query(value=USER_QUERY)
6
zdesam

J'ai réussi à utiliser la constante de classe String dans la requête via l'opérateur SpEL T(), qui vous donne accès aux méthodes statiques et aux constantes d'une classe donnée. Pour String, je dois encapsuler l'expression avec un seul entre guillemets ('), il vous sera probablement également nécessaire (si QuerySyntaxException se produit).

Essayez quelque chose comme ça,

@Query("SELECT u FROM #{#entityName} u " +
       "WHERE u.status = #{T(fully.qualified.path.UserModel).STATUS_ACTIVE}")

Remarque: d'une manière ou d'une autre, cela ne fonctionne pas si vous utilisez UserModel au lieu de # {# entityName}.

Dans les documents, il est brièvement mentionné, voir: https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions-beandef-xml-based

Je ne sais pas depuis quand cela est supporté, j'ai spring-data-jpa 1.4.3, spring-framework 3.2.17

2
WeGa

La réponse à cette question semble être "non" pour une solution standard.

Certaines implémentations JPA peuvent avoir leurs propres solutions, mais l'hibernation pour l'une ne semble pas et ne semble pas prendre en charge les méthodes suggérées par d'autres réponses ici.

1
cmorris

Lorsque vous souhaitez utiliser des constantes directement dans votre annotation @Query, vous pouvez écrire quelque chose comme:

@Query("SELECT u FROM UserModel u WHERE u.status = " + UserModel.STATUS_ACTIVE)
0
h3nrik