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

Persistance des données Java Discussion :

attribut lazy, multi-requête exécuté


Sujet :

Persistance des données Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 15
    Points : 15
    Points
    15
    Par défaut attribut lazy, multi-requête exécuté
    salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    public class Lodger implements Serializable {
     
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long lodgerId;
     
        @OneToOne
        private LodgerStatus lodgerStatus;
     
        private LocalDate entryDate;
     
        private LocalDate releaseDate;
     
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        private List<IdentityCard> identityCardList;
     
        @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
        private OldAddress oldAddress;
     
        @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        private Vehicle vehicle;
     
        @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
        private Phone phone;
     
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        private List<Appointment> appointmentList;
     
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        private List<Reference> referenceList;
     
        @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        @OrderBy
        private List<Bail> bailList;
     
        @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY, mappedBy = "lodger", orphanRemoval = true)
        private List<AccountOperation> accountOperationList;
     
        @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "lodger")
        private List<Contact> contactList;
     
        @OneToMany(fetch = FetchType.LAZY)
        private List<Consultation> consultationList;
     
        @OneToOne(mappedBy = "lodger", fetch = FetchType.LAZY)
        private Drug drug;
     
        @OneToOne(fetch = FetchType.LAZY, mappedBy="lodger")
        private RentAmount rentAmount;
    }
    j'ai fait la requête jpl suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select l from Lodger l where l.birthdate != null and l.releaseDate is null and substring(l.birthdate,6,2)=:month and substring(l.birthdate,9,2)=:day
    or plus de 255 requêtes a lieu

    l'implémentation que j'utilise est hibernate, j'utilise spring, spring data.

    Tous est en lazy, je ne comprend pas pourquoi il y a autant de requête...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    tu peux afficher les requêtes SQL exécutées?

    Aussi: il n'y a pas de birthdate dans ta classe, il viens d'où?
    C'est le select ou ce que tu fais après avec la liste qui génère les 200+ requêtes?
    Ton LodgerStatus n'est pas en lazy ni en fetch type eager. Donc requete supplémentaire.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    J'ai ajouté dans mon post initiale le champs birthdate

    avec la date d'aujourd'hui, il me trouve 1 résultat, mais fait trois résultat....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    Hibernate: 
        select
            lodger0_.lodger_id as lodger_i1_19_,
            lodger0_.active as active2_19_,
            lodger0_.birthdate as birthdat3_19_,
            lodger0_.current_appartment_rent as current_4_19_,
            lodger0_.entry_date as entry_da5_19_,
            lodger0_.first_name as first_na6_19_,
            lodger0_.last_name as last_nam7_19_,
            lodger0_.lodger_status_lodgerStatusId as lodger_10_19_,
            lodger0_.note as note8_19_,
            lodger0_.old_address_addressId as old_add11_19_,
            lodger0_.phone_phoneId as phone_p12_19_,
            lodger0_.release_date as release_9_19_,
            lodger0_.vehicle_vehicleId as vehicle13_19_ 
        from
            lodger lodger0_ 
        where
            (
                lodger0_.birthdate is not null
            ) 
            and (
                lodger0_.release_date is null
            ) 
            and substring(lodger0_.birthdate, 6, 2)=? 
            and substring(lodger0_.birthdate, 9, 2)=?
    Hibernate: 
        select
            drug0_.drug_id as drug_id1_14_2_,
            drug0_.diabete as diabete2_14_2_,
            drug0_.injection as injectio3_14_2_,
            drug0_.injection_period as injectio4_14_2_,
            drug0_.lodger_lodgerId as lodger_l7_14_2_,
            drug0_.medical_drawer_medicalDrawerId as medical_8_14_2_,
            drug0_.medicate as medicate5_14_2_,
            drug0_.medicate_period as medicate6_14_2_,
            lodger1_.lodger_id as lodger_i1_19_0_,
            lodger1_.active as active2_19_0_,
            lodger1_.birthdate as birthdat3_19_0_,
            lodger1_.current_appartment_rent as current_4_19_0_,
            lodger1_.entry_date as entry_da5_19_0_,
            lodger1_.first_name as first_na6_19_0_,
            lodger1_.last_name as last_nam7_19_0_,
            lodger1_.lodger_status_lodgerStatusId as lodger_10_19_0_,
            lodger1_.note as note8_19_0_,
            lodger1_.old_address_addressId as old_add11_19_0_,
            lodger1_.phone_phoneId as phone_p12_19_0_,
            lodger1_.release_date as release_9_19_0_,
            lodger1_.vehicle_vehicleId as vehicle13_19_0_,
            medicaldra2_.medical_drawer_id as medical_1_23_1_,
            medicaldra2_.name as name2_23_1_ 
        from
            drug drug0_ 
        left outer join
            lodger lodger1_ 
                on drug0_.lodger_lodgerId=lodger1_.lodger_id 
        left outer join
            medical_drawer medicaldra2_ 
                on drug0_.medical_drawer_medicalDrawerId=medicaldra2_.medical_drawer_id 
        where
            drug0_.lodger_lodgerId=?
    Hibernate: 
        select
            rentamount0_.rent_amount_id as rent_amo1_35_1_,
            rentamount0_.cash_advance as cash_adv2_35_1_,
            rentamount0_.date_rent_due_generation as date_ren3_35_1_,
            rentamount0_.lodger_lodgerId as lodger_l8_35_1_,
            rentamount0_.payment_due_date as payment_4_35_1_,
            rentamount0_.payment_rent_due_date as payment_5_35_1_,
            rentamount0_.total_rent_amount as total_re6_35_1_,
            rentamount0_.unpaid_balance as unpaid_b7_35_1_,
            lodger1_.lodger_id as lodger_i1_19_0_,
            lodger1_.active as active2_19_0_,
            lodger1_.birthdate as birthdat3_19_0_,
            lodger1_.current_appartment_rent as current_4_19_0_,
            lodger1_.entry_date as entry_da5_19_0_,
            lodger1_.first_name as first_na6_19_0_,
            lodger1_.last_name as last_nam7_19_0_,
            lodger1_.lodger_status_lodgerStatusId as lodger_10_19_0_,
            lodger1_.note as note8_19_0_,
            lodger1_.old_address_addressId as old_add11_19_0_,
            lodger1_.phone_phoneId as phone_p12_19_0_,
            lodger1_.release_date as release_9_19_0_,
            lodger1_.vehicle_vehicleId as vehicle13_19_0_ 
        from
            rent_amount rentamount0_ 
        left outer join
            lodger lodger1_ 
                on rentamount0_.lodger_lodgerId=lodger1_.lodger_id 
        where
            rentamount0_.lodger_lodgerId=?
    si j'enlève le critère de date, il me fait plus de 200 requête... en fait il semble exécuter pour chaque résultat d'autre requête... ce qui n'est pas efficace du tout...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ok je vois le problème et en fait c'est assez complexe. Il est difficile de rendre les oneToOne lazy si ile peuvent être null. C'est compliqué car un lazy nécessite un objet proxy. En général cet objet est une List, un Set etc. Mais ici en oneToOne, cet objet n'existe pas. On pourrait dire qu'il y a un poxy sur Drug, mais comme ton OneToOne autorise les null, hibernate a besoin de savoir si l'objet est null ou pas avant de faire le proxy. Et comme le oneToOne est mappé dans les tables Drug et RentAmount, hibernate a besoin de faire une requête pour ces tables. Donc pas de lazy sur ces deux associations en l'état. Sauf si tu utilise du bytecode instrumentation pour ces associations, mais ça amène d'autres emmerdes.

    En l'état, les solutions simples. Au choix:

    • Déclarer l'association comme nullable=false. Hibernate saura qu'il y a d'office une valeur, fera un proxy et n'exécutera la requête que si on accède à la propriété
    • Inverser la logique. Au lieu d'avoir lodgerId dans la table Drug, avoir un DrugId dans la table Lodger. Idem pour les autre oneToOne qui posent problème. Autrement dit, retirer les mappedBy.
    • Forcer le fetch join dans le select. Par expérience, ça ne marche as à 100%, certaines requêtes sont trop complexe pour que hibernate fasse le fetch join. Je pense que la syntaxe est
    • Code hql : Sélectionner tout - Visualiser dans une fenêtre à part
      select l from Lodger l fetch join l.drug drug, l.rent rent where l.birthdate != null and l.releaseDate is null and substring(l.birthdate,6,2)=:month and substring(l.birthdate,9,2)=:day

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    merci beaucoup j'ai inverser la logique est ça fonctionne très bien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. fonctionnement de l'attribut lazy
    Par Galak extra dans le forum Hibernate
    Réponses: 22
    Dernier message: 10/08/2006, 15h59
  2. Sous-requête excutée plusieurs fois dans une requête
    Par sheridan31 dans le forum Oracle
    Réponses: 8
    Dernier message: 03/07/2006, 16h18
  3. Etat multi requêtes
    Par frevale dans le forum Access
    Réponses: 25
    Dernier message: 02/01/2006, 15h12
  4. [ADO] probleme de multi requête
    Par Grey dans le forum MFC
    Réponses: 3
    Dernier message: 01/12/2005, 16h40
  5. Réponses: 44
    Dernier message: 14/03/2005, 09h43

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