IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JPA Java Discussion :

Sélectionner l'objet avec un max id pour un type donnée


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2015
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2015
    Messages : 53
    Par défaut Sélectionner l'objet avec un max id pour un type donnée
    Salut

    J'ai ces deux classes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Entity
    public class AccountOperation {
     
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long accountOperationId;
     
        @ManyToOne
        @JoinColumn(name = "lodger_id")
        private Lodger lodger;
        private BigDecimal balanceAccountValue;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Entity
    public class Lodger implements Serializable {
     
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long lodgerId;
     
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        private List<AccountOperation> accountOperationList;
     
    }
    Je voudrais aller chercher la dernière opération pour chaque lodger

    en Sql je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * from account_operation ao1
    where ao1.account_operation_id in (
    select max(ao2.account_operation_id) as maxAoId 
    from account_operation ao2 
    )


    In a table account_operation, I have columns: balance, operation_value, transaction_type, transaction_date, lodger_id

    AVec les données suivant
    balance, lodger_id
    20 , 20, 1
    10 , 30, 1
    50 , 50, 2
    70 , 20, 2
    60 , 10, 2
    j'aurais

    balance, operation_value, lodger_id
    10 , 30, 1
    60 , 10, 2
    En jpa,

    j'ai réussi avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select ao1 from AccountOperation ao1 where ao1.accountOperationId  in (select max(ao2.accountOperationId) from AccountOperation ao2)
    Pourquoi ça fonctionne alors que je n'ai pas fait de jointure?

    je me demande si on peut faire mieux?

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Ben si, JPA l'a faite grâce au mapping, c'est un principe de base.

    Pour ce qui est de faire mieux, c'est discutable, ça dépend un peu de ce que tu fais après.
    Ce que tu as codé a le mérite de limiter les lectures... (perso, c'est ce que j'aurais fait pour récupérer uniquement la dernière opération)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2015
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2015
    Messages : 53
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Ben si, JPA l'a faite grâce au mapping, c'est un principe de base.

    Pour ce qui est de faire mieux, c'est discutable, ça dépend un peu de ce que tu fais après.
    Ce que tu as codé a le mérite de limiter les lectures... (perso, c'est ce que j'aurais fait pour récupérer uniquement la dernière opération)

    ok mais pourquoi je n'ai pas besoin de mettre de jointure dans la requête?

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ce code te retourne la dernière opération de ta base. Pas la dernière opération pour chaque lodge. Pas besoin de jointure pour retourner 1 élément. D'ailleurs il n'y a pas de jointure dans ton sql non plus....

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jean.dufour Voir le message
    ok mais pourquoi je n'ai pas besoin de mettre de jointure dans la requête?
    Le JPAQL n'est pas SQL, il fait des choses pour toi en fonction du mapping de tes entities.
    Dans ton exemple, comme le dit tchize_, il n'y a pas de jointure des 2 tables et tant que tu n'accèdes pas à une propriété du "sous-objet", elle ne se fera pas (en lazy loading).
    Pour faire une jointure explicite dans une requête, il faudrait passer par un "join fetch" sur la propriété
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select a from AccountOperation a join fetch a.lodger
    Là, l'objet "lodger" sera initialisé
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2015
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2015
    Messages : 53
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Le JPAQL n'est pas SQL, il fait des choses pour toi en fonction du mapping de tes entities.
    Dans ton exemple, comme le dit tchize_, il n'y a pas de jointure des 2 tables et tant que tu n'accèdes pas à une propriété du "sous-objet", elle ne se fera pas (en lazy loading).
    Pour faire une jointure explicite dans une requête, il faudrait passer par un "join fetch" sur la propriété
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select a from AccountOperation a join fetch a.lodger
    Là, l'objet "lodger" sera initialisé
    @tchize_ a raison, la requête n'est pas bonne, elle ne retourne pas la dernière transaction pour chaque lodger

    en sql je ferais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * from account_operation ao1
    where ao1.account_operation_id in (
    select max(ao2.account_operation_id) as maxAoId 
    from account_operation ao2 group by ao2.lodger_id
    )
    pour le jpa

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select ao1 from AccountOperation ao1 join fetch ao1.lodger where ao1.accountOperationId  in (select max(ao2.accountOperationId) from AccountOperation ao2 group by ao2.lodger.id)
    ça fonctionne

Discussions similaires

  1. [V6] Objet avec taille max de caractères
    Par Anihak dans le forum Deski
    Réponses: 3
    Dernier message: 05/07/2012, 10h57
  2. Deux objets avec le même identifiant pour une session
    Par nicolas_isi dans le forum Hibernate
    Réponses: 6
    Dernier message: 16/07/2009, 09h11
  3. Réponses: 3
    Dernier message: 18/02/2009, 10h00
  4. Souci pour comparer deux objets avec equals()
    Par xillibit dans le forum Langage
    Réponses: 7
    Dernier message: 30/09/2007, 15h41
  5. [Reflection] Opérateurs pour un type donné
    Par Mose dans le forum Framework .NET
    Réponses: 4
    Dernier message: 04/12/2006, 17h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo