Armazenando objects em colunas usando o Hibernate JPA

É 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.