É possível armazenar algo como o seguinte usando apenas uma tabela? Agora, o que o hibernate fará é criar duas tabelas, uma para famílias e outra para pessoas. Eu gostaria que o object familymembers fosse serializado na coluna no database.
@Entity(name = "family") class Family{ private final List familyMembers; } class Person{ String firstName, lastName; int age; }
Este é um design horrível e eu realmente não estou recomendando (você deve apenas criar outra tabela), mas é possível.
Primeiro, você precisará usar um atributo byte[]
para manter uma versão serializada da lista de pessoas que serão armazenadas em um BLOB no database. Então anote, é getter com @Lob
(eu faria o getter e setter private
para não expô-los). Em seguida, exponha getter e setter “fake” para retornar ou definir uma List
do byte[]
. Estou usando o SerializationUtils
do Commons Lang no exemplo abaixo (forneça sua própria class auxiliar se você não quiser importar esta biblioteca) para serializar / desserializar na hora de / para o byte[]
. Não se esqueça de marcar o getter “falso” com @Transcient
ou o Hibernate tentará criar um campo (e falhará porque não poderá determinar o tipo de uma List
).
@Entity(name = "family") class Family implements Serializable { // ... private byte[] familyMembersAsByteArray; public Family() {} @Lob @Column(name = "members", length = Integer.MAX_VALUE - 1) private byte[] getFamilyMembersAsByteArray() { // not exposed return familyMembersAsByteArray; } private void setFamilyMembersAsByteArray((byte[] familyMembersAsByteArray() { // not exposed this.familyMembersAsByteArray = familyMembersAsByteArray; } @Transient public List getFamilyMembers() { return (List ) SerializationUtils.deserialize(familyMembersAsByteArray); } public void setParticipants(List familyMembers) { this.familyMembersAsByteArray = SerializationUtils.serialize((Serializable) familyMembers); } }
Não esqueça de tornar a class Person
Serializable
e adicionar um serialVersionUID
real (estou mostrando apenas um padrão aqui):
public class Person implements Serializable { private static final long serialVersionUID = 1L; // ... private String firstName, lastName; private int age; }
Mas, deixe-me insistir, este é um design horrível e será muito frágil (mudar de Person
pode exigir a “migration” do conteúdo do BLOB para evitar problemas de desserialização e isso se tornará doloroso. Você deve realmente reconsiderar essa ideia e usar outra tabela para a Person
vez disso (ou eu não entendo porque você usa um database).
@Type(type = "serializable") private List familyMembers;
Se você não pode usar annotations de hibernação, tente isto:
@Lob private Serializable familyMembers; public List getFamilyMembers(){ return (List) familyMembers; } public void setFamilyMembers(List family){ familyMembers = family; }
Anote a propriedade com @Column
e defina o tipo como ArrayList
, não apenas como List
. E faça Person
implementar Serializable
.
Mas você deve fazer isso apenas se seus motivos forem muito claros, porque essa é a solução correta em alguns casos muito raros. Como Pascal observou, se você tiver que mudar de Person
terá dores de cabeça.
Você pode criar uma pseudopropriedade (getter e setter) que aceita / devolve o formulário serializado e anotar os familyMembers
com @Transient
. Isso também precisaria anotar os getters, não os campos, para todas as outras propriedades.