Depuis l’API, j’ai pu constater que cela avait quelque chose à voir avec le proxy. Mais je ne pouvais pas trouver beaucoup d'informations sur le proxy et je ne comprenais pas la différence entre appeler session.get
Et session.load
. Quelqu'un pourrait-il m'expliquer ou me diriger vers une page de référence?
Merci!!
Depuis le forum Hibernate :
Ceci du livre Hibernate in Action. Bon on a lu ça ..
Récupération des objets par identifiant L'extrait de code Hibernate suivant récupère un objet Utilisateur de la base de données:
User user = (User) session.get(User.class, userID);
La méthode get () est spéciale car l'identifiant identifie de manière unique une instance unique d'une classe. Par conséquent, il est courant que les applications utilisent l’identificateur en tant que traitement pratique d’un objet persistant. La récupération par identificateur peut utiliser le cache lors de la récupération d'un objet, évitant ainsi que la base de données ne soit touchée si l'objet est déjà mis en cache. Hibernate fournit également une méthode load ():
User user = (User) session.load(User.class, userID);
La méthode load () est plus ancienne; get () a été ajouté à l’API d’Hibernate suite à une requête de l’utilisateur. La différence est triviale:
Si load () ne trouve pas l’objet dans le cache ou la base de données, une exception est levée. La méthode load () ne renvoie jamais la valeur null. La méthode get () renvoie la valeur null si l’objet est introuvable.
La méthode load () peut renvoyer un proxy au lieu d'une instance persistante réelle. Un proxy est un espace réservé qui déclenche le chargement de l'objet réel lors de son premier accès. D'autre part, get () ne retourne jamais un proxy. Choisir entre get () et load () est simple: si vous êtes certain que l’objet persistant existe et que la non-existence est considérée comme exceptionnelle, load () est une bonne option. Si vous n’êtes pas certain qu’il existe une instance persistante avec l’identifiant donné, utilisez get () et testez la valeur de retour pour voir si elle est nulle. L'utilisation de load () a une autre implication: l'application peut récupérer une référence valide (un proxy) vers une instance persistante sans toucher à la base de données pour récupérer son état persistant. Donc, load () peut ne pas lancer d’exception quand il ne trouve pas l’objet persistant dans le cache ou la base de données; l'exception serait levée plus tard, lors de l'accès au proxy. Bien sûr, récupérer un objet par identifiant n’est pas aussi flexible que d’utiliser des requêtes arbitraires.
Bien au moins dans nhibernate, session.Get (id) chargera l’objet à partir de la base de données, tandis que session.Load (id) ne créera qu’un objet proxy sans quitter votre serveur. Fonctionne comme toute autre propriété chargée paresseux dans vos POCO (ou POJO :). Vous pouvez ensuite utiliser ce proxy comme référence à l'objet lui-même pour créer des relations, etc.
Pensez-y comme si vous aviez un objet qui ne garde que l'identifiant et chargera le reste si vous en avez besoin. Si vous ne faites que le transmettre pour créer des relations (comme des FK), l’identifiant est tout ce dont vous aurez besoin.
session.load () retournera toujours un “proxy” (terme Hibernate) sans toucher à la base de données. Dans Hibernate, proxy est un objet avec la valeur d'identifiant donnée, ses propriétés ne sont pas encore initialisées, cela ressemble à un faux objet temporaire. Si aucune ligne n'est trouvée, une exception ObjectNotFoundException est générée.
session.get () frappe toujours la base de données et renvoie l'objet réel, un objet représentant la ligne de la base de données, et non un proxy. Si aucune ligne n'est trouvée, elle retourne null.
La performance avec ces méthodes rend également diff. entre deux...
Un point supplémentaire:
la méthode get de la session Hibernate Session renvoie la valeur null si l'objet n'est pas trouvé dans le cache ni dans la base de données. La méthode load () lève une exception ObjectNotFoundException si l’objet n’est pas trouvé dans le cache ni dans la base de données, mais ne renvoie jamais la valeur null.
Une des conséquences indirectes de l'utilisation de "load" au lieu de "get" est que le verrouillage optimiste à l'aide d'un attribut de version peut ne pas fonctionner comme prévu. Si un chargement crée simplement un proxy et ne lit pas à partir de la base de données, la propriété version n'est pas chargée. La version ne sera chargée que lorsque/si vous vous référez ultérieurement à une propriété de l'objet, ce qui déclenche une sélection. Entre-temps, une autre session peut mettre à jour l'objet et votre session n'aura pas la version d'origine dont elle a besoin pour effectuer la vérification de verrouillage optimiste. La mise à jour de votre session écrasera donc la mise à jour de l'autre session sans aucun avertissement.
Voici une tentative pour esquisser ce scénario avec deux sessions utilisant un objet avec le même identifiant. La version initiale de l'objet dans la base de données est 10.
Session 1 Session 2
--------- ---------
Load object
Wait a while..
Load object
Modify object property
[triggers db 'select' -
version read as 10]
Commit
[triggers db update,
version modified to 11]
Modify object property
[triggers db 'select' -
version read as 11]
Commit
[triggers db update,
version modified to 12]
En réalité, nous voulons que la validation de la session 1 échoue avec une exception de verrouillage optimiste, mais elle réussira ici.
L'utilisation de "get" au lieu de "load" permet de résoudre le problème, car get émettra immédiatement une sélection et les numéros de version seront chargés au bon moment pour la vérification de verrouillage optimiste.
De plus, nous devons faire attention en utilisant load car cela lève une exception si l'objet n'est pas présent. Nous ne devons l'utiliser que lorsque nous sommes sûrs que cet objet existe.
load () ne peut pas trouver l’objet dans le cache ou la base de données, une exception est levée et la méthode load () ne renvoie jamais la valeur null.
la méthode get () renvoie la valeur null si l’objet est introuvable. La méthode load () peut renvoyer un proxy au lieu d'une instance persistante réelle. Get () ne renvoie jamais un proxy.
Une excellente explication se trouve sur http://www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Il retournera toujours un "proxy" (terme Hibernate) sans toucher à la base de données.
Dans Hibernate, le proxy est un objet avec la valeur d'identificateur donnée, ses propriétés ne sont pas encore initialisées, cela ressemble simplement à un faux objet temporaire.
Il retournera toujours un objet proxy avec la valeur d'identité donnée, même si la valeur d'identité n'existe pas dans la base de données. Toutefois, lorsque vous essayez d’initialiser un proxy en récupérant ses propriétés de la base de données, il va frapper la base de données avec l’instruction select. Si aucune ligne n'est trouvée, une exception ObjectNotFoundException sera levée.
session.get ():
Il frappe toujours la base de données (s'il ne se trouve pas dans le cache) et renvoie l'objet réel, un objet représentant la ligne de la base de données, et non un proxy.
Si aucune ligne n'est trouvée, elle renvoie la valeur null.