web-dev-qa-db-fra.com

Quand et pourquoi les entités JPA doivent-elles implémenter une interface sérialisable?

La question est dans le titre. Ci-dessous, je viens de décrire certaines de mes pensées et conclusions.

Lorsque j’avais un modèle de domaine très simple (3 tables sans aucune relation), toutes mes entités n’implémentaient PAS Serializable.

Mais lorsque le modèle de domaine est devenu plus complexe, j'ai obtenu RuntimeException qui indiquait qu'une de mes entités n'avait pas implémenté Serializable.

J'utilise Hibernate comme une implémentation JPA.

Je me demande:

  1. S'agit-il d'une exigence/d'un comportement spécifique au fournisseur?
  2. Que se passe-t-il avec mes entités sérialisables? Devraient-ils être sérialisables pour le stockage ou le transfert?
  3. A quel moment il devient nécessaire de rendre mon entité sérialisable?
125
Roman

Cela se produit généralement si vous mélangez des requêtes HQL et SQL natives. Dans HQL, Hibernate mappe les types que vous transmettez à ce que le DB comprend. Lorsque vous exécutez du SQL natif, vous devez alors effectuer le mappage vous-même. Si vous ne le faites pas, le mappage par défaut consiste à sérialiser le paramètre et à l'envoyer à la base de données (dans l'espoir qu'il le comprenne).

53
Aaron Digulla

Selon les spécifications JPA:

Si une instance d'entité doit être transmise par valeur en tant qu'objet détaché (par exemple, via une interface distante), la classe d'entités doit implémenter l'interface Serializable.

"JSR 220: Enterprise JavaBeansTM, version 3.0 Java API de persistance version 3.0, version finale du 2 mai 2006"

105
Conor

Vous avez besoin que vos entités soient Serializable si vous devez les transférer par câble (les sérialiser sur une autre représentation), stockez-les dans une session http (elle-même sérialisée sur le disque dur par le conteneur de servlets). ), etc.

Juste pour des raisons de persistance, Serializable n'est pas nécessaire, du moins avec Hibernate. Mais il est recommandé d’en faire Serializable.

46
Bozho

Pour compléter la réponse de Nice de Conor qui faisait référence aux spécifications JSR-317. En règle générale, les projets EAR consistent en un module EJB avec les EJB exposés via une interface distante. Dans ce cas, vous devez rendre vos beans entité sérialisables car ils sont agrégés dans l'EJB distant et sont conçus pour être câblés via le réseau.

Un projet de guerre JEE6 sans CDI: peut contenir EJB lite soutenu par des entités JPA non sérialisables.

Un projet de guerre JEE6 avec CDI: Les beans utilisant la portée de la session, de l'application ou de la conversation doivent être sérialisables, mais les beans utilisant la portée de la requête ne doivent pas nécessairement être sérialisables. Ainsi, les beans entité JPA sous-jacents - suivrait la même sémantique.

8
Sym-Sym

Selon hibernate docs , en utilisant l'annotation @JoinColumn:

Il a encore un paramètre nommé referencedColumnName. Ce paramètre déclare la colonne de l'entité ciblée qui sera utilisée pour la jointure. Notez que lorsque vous utilisez referencedColumnName dans une colonne de clé non primaire, la classe associée doit être Serializable.

7
aman maharjan

Je crois que votre problème est lié au fait d’avoir un champ d’un type complexe (classe) qui n’est pas annoté. Dans de tels cas, la gestion par défaut stockera l'objet dans sa forme sérialisée dans la base de données (ce qui n'est probablement pas ce que vous vouliez faire). Exemple:

Class CustomerData {
    int getAge();
    void setAge(int age);
}

@Entity
Class Customer {
  CustomerData getCustomerData();
  void setCustomerData(CustomerData data)
}

Dans le cas ci-dessus, CustomerData sera enregistré dans un champ de tableau d'octets de la base de données sous sa forme sérialisée.

6
Avner Levy

Les classes doivent implémenter Serializable si vous souhaitez les sérialiser. Cela n'est pas directement lié à JPA et la spécification JPA n'exige pas que les entités soient sérialisables. Si Hibernate se plaint vraiment à ce sujet, je suppose que c'est un bogue d'Hibernate, mais je suppose que vous faites directement ou indirectement quelque chose de différent avec les entités, ce qui les oblige à être sérialisables.

4
jarnbjo

Veuillez vous référer à http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to il est indiqué que l'implémentation de Java.io.Serializable est simplement requise pour le transfert de données via IIOP ou JRMP ( RMI) entre les instances JVM. Dans le cas d'une application Web pure, les objets de domaine sont parfois stockés dans HTTPSession à des fins de mise en cache/d'optimisation. Une session http peut être sérialisée (passivation) ou en cluster. Dans les deux cas, tout le contenu doit être sérialisable.

3
Arun K

Si nous ne parlons que de persistance, Serializable n'est pas nécessaire, mais il est recommandé de créer les entités Serializable.

Si nous exposons des objets domain/entities directement exposés à la couche de présentation, au lieu d'utiliser DTO, dans ce cas nous devons implémenter Serializable. Ces objets de domaine peuvent être stockés dans HTTPSession à des fins de mise en cache/d'optimisation. Une session http peut être sérialisée ou en cluster. Et il est également nécessaire pour transférer des données entre JVM- instances.

Lorsque nous utilisons DTO pour découpler la couche de persistance et la couche de service, marquer les objets de domaine comme Serializable serait contre-productif et constituerait une violation de "encapsulation". Ensuite, cela devient un anti-modèle.

identificateurs composites

La classe de clé primaire doit être sérialisable.

Modèles POJO

Si une instance d'entité doit être utilisée à distance en tant qu'objet détaché, la classe d'entité doit implémenter l'interface Serializable.

Cache
De plus, si vous implémentez un clustered deuxième niveau cache, alors vos entités doivent être serializable. L’identifiant doit être Serializable car c’est une exigence JPA car le identifier peut être utilisé comme clé pour une entrée de cache de second niveau.

Et lorsque nous sérialisons des entités, assurez-vous de fournir explicitement serialVersionUID avec un modificateur d'accès privé. Parce que si une classe serializable ne déclare pas explicitement un serialVersionUID, alors l'exécution de la sérialisation calculera une valeur par défaut serialVersionUID pour cette classe en fonction de divers aspects de la classe, comme décrit dans la spécification de sérialisation d'objets Java (TM). Le calcul par défaut de serialVersionUID est très sensible aux détails de classe qui peuvent varier en fonction de l'implémentation du compilateur et peut donc entraîner un inattendu InvalidClassExceptions lors de la désérialisation.

1
Ankur Singhal

frappe à distance en utilisant postman ou ajax ou angular js etc ....., peut provoquer le cycle de répétition avec l'exception StackOverflow avec Jackson Fastxml.So, il est préférable d'utiliser un sérialiseur.

1
tamil

lorsque des entités JPA sont utilisées en tant que paramètres ou en tant que valeurs renvoyées par les opérations EJB distantes

0
SAR

C’est aussi l’erreur générée lorsque vous transmettez un ID mal typé en tant que second paramètre à quelque chose comme em.find () (c’est-à-dire en transmettant l’entité elle-même plutôt que son ID). Je n'ai pas encore trouvé nécessaire de déclarer les entités JPA sérialisables. Ce n'est vraiment nécessaire que si vous utilisez referenceColumnName comme décrit par aman.

0
Amalgovinus
  1. A quel moment il devient nécessaire de rendre mon entité sérialisable?

Implémentation de ehcache avec diskstore en tant que cache de second niveau (c'est-à-dire en utilisant @Cacheable annotation sur une entité ou une méthode de référentiel/service) requiert Serializable, sinon le cache échouera (NotSerializableException) pour écrire l'entité dans le cache de disque.

0
Michal