Comment faire pour retourner un objet personnalisé à partir d'un Spring Data JPA GROUPE PAR requête
Je suis élaboration d'un Ressort de Démarrage de l'application avec Spring Data JPA. Je suis en utilisant une mesure de la requête JPQL de groupe par un certain domaine et obtenir le nombre. Suite à mon dépôt de la méthode.
@Query(value = "select count(v) as cnt, v.answer from Survey v group by v.answer")
public List<?> findSurveyCount();
C'est de travailler et le résultat est obtenu comme suit:
[
[1, "a1"],
[2, "a2"]
]
Je voudrais obtenir quelque chose comme ceci:
[
{ "cnt":1, "answer":"a1" },
{ "cnt":2, "answer":"a2" }
]
Comment puis-je y parvenir?
Vous devez vous connecter pour publier un commentaire.
Solution pour les requêtes JPQL
C'est pris en charge pour les requêtes JPQL dans le Spécification JPA.
Notes importantes
MyBean
et il est dans le paquetcom.path.to
, le chemin d'accès complet à la fève seracom.path.to.MyBean
. De simplement fournir desMyBean
ne fonctionnera pas (sauf si la classe d'haricot est dans le package par défaut).new
mot-clé.SELECT new com.path.to.MyBean(...)
de travail, alors queSELECT com.path.to.MyBean(...)
ne sera pas.@Query("SELECT ...")
, ou@Query(value = "SELECT ...")
, ou@Query(value = "SELECT ...", nativeQuery = false)
de travail, alors que@Query(value = "SELECT ...", nativeQuery = true)
ne fonctionnera pas. C'est parce que les requêtes sont transmises sans modifications de la JPA fournisseur, et sont exécutées sur le SGBD sous-jacent en tant que tel. Depuisnew
etcom.path.to.MyBean
ne sont pas valides mots-clés SQL, SGBD puis lève une exception.Solution pour les requêtes
Comme indiqué ci-dessus, le
new ...
syntaxe est une JPA-mécanisme de prise en charge et fonctionne avec tous les fournisseurs JPA.. Cependant, si la requête elle-même n'est pas une JPA requête, qui est, il est originaire de la requête, lenew ...
syntaxe ne fonctionnera pas tant que la requête est transmise directement à la sous-jacentes SGBDR, qui ne comprend pas lanew
mot-clé, car il ne fait pas partie de la norme SQL.Dans des situations comme celles-ci, classes de haricots doivent être remplacés avec Printemps De Projection De Données interfaces.
Utiliser le SQL
AS
mot-clé pour mapper les champs de résultat de la projection des propriétés de non équivoque.Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate class [SurveyAnswerReport] [select new SurveyAnswerReport(v.answer,count(v.id)) from com.furniturepool.domain.Survey v group by v.answer] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) at org.hibernate.jpa.spi.AbstractEnti..........
SurveyAnswerReport
dans votre sortie. Je suppose que vous avez remplacéSurveyAnswerStatistics
avec votre propre classeSurveyAnswerReport
. Vous devez spécifier le nom de classe entièrement qualifié.com.domain.dto.SurveyAnswerReport
.JpaRepository
? Est la configuration que j'ai manqué ?CASE
,WHEN
,THEN
etgetDate()
ne sont pas valides JPQL mots-clés), qui est pourquoi les choses ne fonctionnent pas pour vous.Couldn't find PersistentEntity for type class com.sun.proxy.$Proxy...
. Ce qui peut être mauvais ?Cette requête SQL retour Liste< Object[] > serait.
Vous pouvez le faire de cette façon:
Je sais que c'est une vieille question et il a déjà été répondu, mais voici une autre approche:
L'utilisation d'interfaces, vous pouvez obtenir de plus simple code. Pas besoin de créer manuellement et appellent des constructeurs
Étape 1: Déclarer intefrace avec les champs requis:
Étape 2: Sélectionnez les colonnes avec le même nom que le getter dans l'interface et de retour intefrace de référentiel méthode:
définir une coutume de classe pojo dire sureveyQueryAnalytics et de stocker la requête a retourné la valeur dans votre personnalisé de classe pojo
Je n'aime pas les noms de type de java dans les chaînes de requête et de les traiter avec un constructeur.
Spring JPA appelle implicitement constructeur avec le résultat de la requête dans la table de hachage paramètre:
Code des besoins de Lombok, pour résoudre @Getter
Je viens de résoudre ce problème :
@Query(value = "SELECT ...", nativeQuery = true
)) donc, je recommande à définir des DTO en utilisant l'interface .J'ai utilisé personnalisé DTO (interface) pour mapper une requête native à l'approche la plus souple et la refactorisation-fort.
Le problème que j'ai eu avec ce - qu'étonnamment, l'ordre des champs dans l'interface et les colonnes dans la requête questions. J'ai eu de travail par la commande d'interface de getters par ordre alphabétique et puis, ordonnant que les colonnes dans la requête de la même façon.
Le code ci-dessus a fonctionné pour moi.