使用 Hibernate JPA 在列中存储对象 [英] Storing Objects in columns using Hibernate JPA

查看:18
本文介绍了使用 Hibernate JPA 在列中存储对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以仅使用一张表来存储如下内容?现在,hibernate 会做的是创建两张表,一张用于家庭,一张用于人.我希望将 familymembers 对象序列化到数据库中的列中.

Is it possible to store something like the following using only one table? Right now, what hibernate will do is create two tables, one for Families and one for people. I would like for the familymembers object to be serialized into the column in the database.

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

    private final List<Person> familyMembers;

}

class Person{

   String firstName, lastName;
   int age;

}

推荐答案

这是一个可怕的设计,我真的不推荐它(你应该创建另一个表)但它是可能的.

This is an horrible design and I'm really not recommending it (you should just create another table) but it is possible.

首先,您需要使用 byte[] 属性来保存将存储在数据库中的 BLOB 中的人员列表的序列化版本.所以用 @Lob 注释它的 getter(我会让 getter 和 setter private 不公开它们).然后,公开假"getter 和 setter 以从 byte[] 返回或设置 List.我正在使用 SerializationUtils 来自下面示例中的 Commons Lang(如果您不想导入此库,请提供您自己的帮助程序类)以在 byte[] 中动态序列化/反序列化.不要忘记用 @Transcient 标记假"getter,否则 Hibernate 将尝试创建一个字段(并失败,因为它无法确定 List).

First, you'll need to use a byte[] attribute to hold a serialized version of the list of persons that will be stored in a BLOB in the database. So annotate it's getter with @Lob (I would make the getter and setter private to not expose them). Then, expose "fake" getter and setter to return or set a List<Person> from the byte[]. I'm using SerializationUtils from Commons Lang in the sample below (provide you own helper class if you don't want to import this library) to serialize/deserialize on the fly to/from the byte[]. Don't forget to mark the "fake" getter with @Transcient or Hibernate will try to create a field (and fail because it won't be able to determine the type for a 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);
    }
}

不要忘记创建PersonSerializable 并添加一个真正的serialVersionUID(我只是在这里显示一个默认值):

Don't forget to make the Person class Serializable and to add a real serialVersionUID (I'm just showing a default here):

public class Person implements Serializable {

   private static final long serialVersionUID = 1L;

   // ...

   private String firstName, lastName;
   private int age;

}

但是,让我坚持,这是一个可怕的设计,它将非常脆弱(更改 Person 可能需要迁移"BLOB 的内容以避免反序列化问题,这将变得很痛苦. 你真的应该重新考虑这个想法,并为 Person 使用另一个表(否则我不明白你为什么使用数据库).

But, let me insist, this is an horrible design and it will be very fragile (changing Person might require to "migrate" the content of the BLOB to avoid deserialization issues and this will become painful. You should really reconsider this idea and use another table for the Person instead (or I don't get why you use a database).

这篇关于使用 Hibernate JPA 在列中存储对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆