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

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

问题描述

仅使用一个表可以存储类似下面的内容吗?现在,hibernate会做的是创建两个表,一个用于家庭,一个用于人。我希望将familymembers对象序列化到数据库的列中。

  @Entity(name =family) 
class Family {

private final List< Person>家庭成员;

}

class Person {

字符串firstName,lastName;
int age;

$ b $ / code>


解决方案

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

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

  @Entity(name =family) 
类Family实现Serializable {

// ...

private byte [] familyMembersAsByteArray;

public Family(){}

@Lob
@Column(name =members,length = Integer.MAX_VALUE - 1)
private byte [] getFamilyMembersAsByteArray(){//未公开
return familyMembersAsByteArray;

$ b $ private void setFamilyMembersAsByteArray((byte [] familyMembersAsByteArray(){// not exposed
this.familyMembersAsByteArray = familyMembersAsByteArray;
}

@Transient
public List< Person> getFamilyMembers(){
return(List< Person>)SerializationUtils.deserialize(familyMembersAsByteArray);
}
$ b $ public void setParticipants(List familyMembers){
this.familyMembersAsByteArray = SerializationUtils.serialize((Serializable)familyMembers);
}
}

不要忘记让 Person class Serializable 和添加一个真正的 serialVersionUID (我只是在这里显示一个默认值):

  public class Person implements Serializable {

private static final long serialVersionUID = 1L;

// ...

private String firstName, lastName;
privat年龄;

}

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


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.

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);
    }
}

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;

}

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天全站免登陆