2010-06-10 4 views

Répondre

0

Je pense que c'est à cause de la prise en charge de la mise en cache. Lorsque vous utilisez un cache permanent ou toute mise en cache qui distribue un objet via le réseau, vous devez vous assurer que les objets peuvent être transportés dans un format commun, en l'occurrence la sérialisation Java.

+1

mais est-ce la mise en cache sur l'option par défaut de plusieurs JVM? Je pense que ce n'est pas le cas, et si je configure le cache ou le cluster, je rendrai mes objets sérialisables. Mais pourquoi hiberner doit-il me forcer à utiliser la sérialisation lorsque je n'utilise pas de cache distribué? – Reddy

+0

Non, ce n'est pas activé par défaut. J'imagine que l'implémentation de l'implémentation Serializable devrait permettre à un développeur de reconnaître qu'un objet de valeur peut être soumis à la sérialisation et devrait donc être conçu de cette manière. Juste une supposition, je n'y ai jamais vraiment réfléchi et je ne l'ai même pas reconnu avant d'avoir lu votre question. – perdian

0

Je ne le vois franchement pas autrement. Si vous n'êtes pas la structure de table définissant et générant des instructions d'insertion pour accueillir des objets, l'instruction SQL générée est une chaîne en elle-même et elle insère une autre chaîne de texte (vos données sérialisées) dans un champ d'une table. Quoi que vous insériez dans une base de données doit être une chaîne dans ce cas, il ne peut pas être un objet avec des méthodes dépendantes du langage, sauf si vous concevez explicitement une table pour stocker des données comme ça.

+1

1. get() et load() n'insèrent rien dans la table, récupèrent juste une entité existante, 2. le point entier de Hibernate est le mapping relationnel objet (ORM), c'est-à-dire que les propriétés de l'objet sont mappées colonnes de table un par un (plus ou moins) d'une manière explicitement conçue. Aucune sérialisation ne se produit par défaut, sauf si vous le définissez explicitement (et que vous avez probablement besoin d'un type de mappage personnalisé pour cela). –

+0

Bon point. J'ai mal interprété votre question. Cependant, je les ai déjà utilisés pour stocker des références, c'est-à-dire des ids pour des objets, de sorte que la sérialisation a du sens en tant qu'approche de stockage. Mon expérience peut être un peu limitée dans ce cas. – Raine

1

Ce n'est pas tout à fait vrai. From the Javadoc, la signature des méthodes pertinentes est:

public Object get(Class clazz, Serializable id) ... 
public Object load(Class theClass, Serializable id) ... 

(pièces et autres versions surchargées non pertinentes omis par souci de concision). Ainsi, l'entité à charger peut appartenir à n'importe quelle classe, seul son identificateur doit être sérialisable.

Les entités en effet ne peuvent pas être sérialisables, selon cette citation de Java Persistence with Hibernate, ch. 13.3.2:

Les instances persistantes sont stockées dans le cache de second niveau sous une forme désassemblée . Pensez au désassemblage comme un processus un peu comme la sérialisation (l'algorithme est beaucoup, beaucoup plus rapide que la sérialisation Java, cependant).

Donc je suppose que les identifiants (dans le cache de requête) ne sont pas non plus sérialisés. Je ne pouvais pas trouver d'explication sur pourquoi id est déclaré Serializable, et manquant de cela, je ne peux que deviner. L'API a besoin d'un type pour le paramètre id, qui doit être un supertype commun d'au moins les types d'identificateur fréquemment utilisés Number et String, et à l'exception de Object, Serializable est le seul choix.

+1

vrai, mais pourquoi même Identifier doit être sérialisable? – Reddy

5

D'abord, le fait que Hibernate utilise Serializable dans une signature ne signifie pas que Hibernate va sérialisation quoi que ce soit, cela signifie simplement que les paramètres sont sérialisable si le besoin se fait sentir.

Ensuite, je ne pouvais pas trouver une référence absolue, mais je pense que l'argument le plus fort est:

  • Les entités sont Ids utiliser comme clé pour la mise en cache (premier niveau, deuxième niveau) et peut être envoyer sur le fil

Certains arguments les plus faibles (ou non l'argument à tous):

  • le Session lui-même peut être potentiellement sérialisé (par exemple pour être stockés dans le HttpSession)
  • Hibernate a besoin d'un super type pour entityId (y compris PK composite)

Compte tenu de tout cela, je pense qu'il est logique d'appliquer les utilisateurs de l'API pour passer un Serializable entityId, ce qui permet de ne pas fermer une porte et pour éviter toute limitation ultérieure (oups, vous ne pouvez pas activer la mise en cache de second niveau car ce PK n'est pas Serializable). C'est IMO une décision de conception beaucoup mieux que d'utiliser Object. Et pour être honnête, je ne vois pas d'ennui avec ça.

+0

Je n'ai vraiment aucun problème avec Serializable. Mais mon point est pourquoi quelqu'un d'autre doit forcer quelque chose sur moi, même si c'est une très bonne pratique? – Reddy

Questions connexes