10
votes

La propriété @Transient doit-elle être utilisée dans des égaux / HashCode / Tostring?

J'ai des entités JPA où certaines propriétés sont annotées avec @Transient .

devrais-je utiliser ces propriétés dans égaux / hashcode / tostring méthodes?

Ma première pensée est non mais je ne sais pas pourquoi.

  • Conseils?
  • Idées?
  • Explications?

0 commentaires

3 Réponses :


0
votes

Les deux usages typiques de @Transient et transitoires dont je suis au courant, êtes de les utiliser soit pour des choses qui ne peuvent pas être sérialisées / persistées (par exemple une ressource distante poignée ) ou des propriétés calculées qui peuvent être reconstruites à partir d'autres.

pour Données calculées , il n'a aucun sens de les utiliser dans la relation d'égalité ( égaux / hashcode ), car il serait redondant. La valeur est calculée hors d'autre valeur déjà utilisée dans l'égalité. Il peut toutefois tout de même loger de les imprimer dans Tostring (par exemple un prix de base et un rapport servent à calculer le prix réel).

pour Données non sérialisables / perspectives , cela dépend. Je peux imaginer une poignée à une ressource qui n'est pas sérialisable, mais vous pouvez toujours comparer le nom de la ressource que le manche représente. Idem pour tostring , peut-être impressionner le nom de la ressource de la poignée est utile.

C'était mon 2 cent, mais si vous expliquez votre usage particulier de @Transient , une personne peut peut-être donner un meilleur conseil.


0 commentaires

7
votes

Le cas de tostring () est différent, vous pouvez faire ce que vous voulez avec Tostring () donc je ne couvrirai que égal () (et hashcode () ).

Premièrement, la règle: Si vous souhaitez stocker un objet dans une liste , mappe ou a définir alors c'est une exigence que est égal à et hashcode est mis en œuvre afin qu'ils obéissent donc au contrat standard Comme spécifié dans la documentation .

Maintenant, comment implémenter Equals () et hashcode () ? Une idée "naturelle" serait d'utiliser les propriétés mappées comme id dans le cadre du égale () : xxx

Malheureusement, cette solution a un problème majeur : lorsque vous utilisez des identifiants générés, les valeurs ne sont pas attribuées avant que d'une entité ne devienne persistante donc si un transitoire L'entité est ajoutée à un fichier avant d'être enregistré, son code de hachage changera lorsqu'il est dans l'ensemble et ceci enfreint le contrat de l'ensemble .

L'approche recommandée consiste ainsi à utiliser les attributs qui font partie de la touche c'est-à-dire une combinaison d'attributs unique pour chaque instance avec la même identité de la base de données. Par exemple, pour la classe utilisateur, cela pourrait être le nom d'utilisateur: xxx

La documentation de référence Hibernate résume celle-ci comme suit:

" N'utilisez jamais l'identifiant de la base de données pour implémenter l'égalité; utilisez une clé d'entreprise, une combinaison d'attributs uniques, généralement immuables, d'attributs . L'identifiant de la base de données changera si un objet transitoire est rendu persistant. Si le L'instance transitoire (généralement avec des instances détachées) est détenue dans un SET , la modification du fichier Hashcode casse le contrat du fichier défini . Attributs pour les clés de l'entreprise Ne devez pas être aussi stable que les clés principales de base de données, il vous suffit de garantir la stabilité tant que les objets sont dans le même ensemble. " - 12.1.3. Considérant l'identité d'objet

" Il est recommandé de mettre en œuvre égale () et hashcode () à l'aide de l'égalité des touches commerciales . L'égalité des clés métier signifie que le < Code> Equals () La méthode ne compare que les propriétés qui forment la clé Business. C'est une clé qui identifierait notre instance dans le monde réel (une clé de candidature naturelle) "- 4.3. Mise en œuvre égales () et HASHCODE ()

Alors, retour à la question initiale:


0 commentaires

0
votes

Exception peut-être vient de le laisser être transitère et dans le même temps que vous fournissez wrecroveObject () et lisaBject () où vous le traitez .


0 commentaires