10
votes

Stocker des objets dans des colonnes à l'aide de Hibernate JPA

est-il possible de stocker quelque chose comme les suivants en utilisant une seule table? En ce moment, ce que l'hibernate fera est de créer deux tables, une pour les familles et une pour les personnes. J'aimerais que l'objet FamilyMembers soit sérialisé dans la colonne de la base de données.

@Entity(name = "family")
class Family{

    private final List<Person> familyMembers;

}

class Person{

   String firstName, lastName;
   int age;

}


3 commentaires

Ce n'est pas clair. Si vous voyez une famille de personnes en tant que groupe de personnes, vous avez besoin d'une nouvelle table pour la famille, sauf si vous représentez la famille avec un simple type comme un entier ou une chaîne.


OT: Ce serait un mauvais design.


Si une famille a 3 membres, quelle valeur vous attendez-vous à voir dans la colonne de la base de données?


4 Réponses :


0
votes

Vous pouvez créer de pseudoproperty (getter andingter) qui accepte / renvoie la forme sérialisée et annotant le FamilyMembers avec @Transient . Cela aurait également besoin d'annoter les getters, pas des champs, pour toutes les autres propriétés.


0 commentaires

1
votes

Annotate la propriété avec @Column et définissez le type à ArrayList , pas seulement Liste . Et faire personne implémenter sérialisable .

Mais vous ne devez le faire que si vos motivations sont très claires, car c'est la solution correcte dans certains cas très rares. Comme l'a noté Pascal, si vous deviez jamais changer personne vous aurez des maux de tête.


2 commentaires

Je suis à peu près sûr que cela échouerait avec un java.lang.classcastException: java.util.arrayList ne peut pas être jeté à java.sql.blob


Oui, j'ai regardé une classe de mienne où je reçois la même situation - cela fonctionne avec Lob, et avec la spécification du type concret (arraylist). Mise à jour de la réponse



14
votes

C'est un design horrible et je ne le recommande vraiment pas (vous devriez simplement créer une autre table) mais c'est possible.

Tout d'abord, vous devrez utiliser un attribut octet [] code> pour contenir une version sérialisée de la liste des personnes qui seront stockées dans une blob dans la base de données. Ainsi, annotate c'est getter avec @lob code> (je ferais le getter et le Setter privé code> pour ne pas les exposer). Ensuite, exposez "Faux" getter et Setter pour renvoyer ou définir une liste code> à partir du octet [] code>. J'utilise SerializationUtils code> des Commons Lang dans l'échantillon ci-dessous (fournissez votre propre classe d'assistance si vous ne souhaitez pas importer cette bibliothèque) sur Serialize / désériorialiser à la volée / depuis le octet [] code>. N'oubliez pas de marquer le "faux" getter avec @Transcient code> ou hibernate tentera de créer un champ (et d'échouer car il ne pourra pas déterminer le type d'une liste ).

public class Person implements Serializable {

   private static final long serialVersionUID = 1L;

   // ...

   private String firstName, lastName;
   private int age;

}


1 commentaires

Pourquoi ne pouvez-vous pas utiliser la personne de base de données, peut-être parce que l'utilisation est inutile? Si tout ce dont j'ai besoin, c'est stocker une liste de quelque chose, je n'ai pas besoin de la mettre dans une base de données séparée.



4
votes
@Lob
private Serializable familyMembers;

public List<Person> getFamilyMembers(){
    return (List) familyMembers;
}

public void setFamilyMembers(List<Person> family){
    familyMembers = family;
}

1 commentaires

Oui, mais ce n'est pas une annotation JPA.