Действительно ли возможно сохранить что-то как следующее использование только одной таблицы? Прямо сейчас, что в спящем режиме, сделает, составляют две таблицы, один для Семейств и один для людей. Я хотел бы за объект familymembers быть сериализированным в столбец в базе данных.
@Entity(name = "family")
class Family{
private final List<Person> familyMembers;
}
class Person{
String firstName, lastName;
int age;
}
@Type(type = "serializable")
private List<Person> familyMembers;
Если вы не можете использовать аннотации в гибернации, попробуйте это:
@Lob
private Serializable familyMembers;
public List<Person> getFamilyMembers(){
return (List) familyMembers;
}
public void setFamilyMembers(List<Person> family){
familyMembers = family;
}
Вы можете создавать псевдопроперти (Getter и Setter), который принимает / возвращает сериализованную форму и аннотируйте FamilyMember
С @transient
. Это также потребуется аннотировать Геттерс, а не поля, для всех других свойств.
Аннотайте свойство с @Column
и определите тип, чтобы быть ArrayList
, а не только в списке
. И сделать человек
сериализация
.
Но вы должны сделать это только в том случае, если ваши мотивы очень ясны, потому что это правильное решение в некоторых очень редких случаях. Как отметил Паскаль, если вам когда-нибудь нужно изменить человек
, у вас будут головные боли.
Это ужасный дизайн, и я действительно не рекомендую его (вы должны просто создать другую таблицу), но это возможно.
Сначала вам нужно использовать атрибут байт[]
, чтобы хранить сериализованную версию списка лиц, которая будет храниться в BLOB базе данных. Поэтому аннотируйте его геттером с помощью @Lob
(я бы сделал геттер и сеттер private
, чтобы не выставлять их на всеобщее обозрение). Затем, выставьте "фальшивый" геттер и сеттер для возврата или установки List
из байта[]
. Я использую SerializationUtils
из Commons Lang в примере ниже (предоставьте свой вспомогательный класс, если вы не хотите импортировать эту библиотеку) для сериализации/десериализации на лету в/из байта []
. Не забудьте отметить "поддельный" геттер с помощью @Transcient
или Hibernate попытается создать поле (и не сможет определить тип для 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<Person> getFamilyMembers() {
return (List<Person>) SerializationUtils.deserialize(familyMembersAsByteArray);
}
public void setParticipants(List familyMembers) {
this.familyMembersAsByteArray = SerializationUtils.serialize((Serializable) familyMembers);
}
}
Не забудьте сделать класс Person
Serializable
и добавить реальный serialVersionUID
(я просто показываю здесь значение по умолчанию):
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
// ...
private String firstName, lastName;
private int age;
}
Но, позвольте мне настаивать, это ужасный дизайн, и он будет очень хрупким (изменение Человек
может потребовать "перенести" содержимое BLOB, чтобы избежать проблем с десериализацией, и это станет болезненным. Вам действительно следует пересмотреть эту идею и вместо этого использовать другую таблицу для Person
(или я не понимаю, зачем вы используете базу данных).