为什么一个类实现了Serializable接口?

时间:2011-09-04 11:12:22

标签: java jpa

@Entity
public class Husband implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne
   private Wife wife;

}

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne(mappedBy="wife")
   private Husband husband;

}
  1. 广义上什么是Serializable
  2. 为什么一个类实现Serializable接口?
  3. 为什么单独的丈夫成员有@OnetoOne(mappedBy =“妻子”),但妻子成员没有@OnetoOne(mappedBy =“丈夫”)

4 个答案:

答案 0 :(得分:10)

  1. 从广义上讲,序列化是Java为开发人员提供持久存储任何对象状态的方式。

  2. 如果开发人员希望由于某种原因将其编码类的实例持久化到后备存储,则需要将该类声明为实现Serializable。

  3. 上述代码代表丈夫与妻子之间的一对一关系。这基本上意味着每个妻子都与一个丈夫有关,每个丈夫都与一个妻子有关。 :-)同样在上述关系中,丈夫是[实体 - 关系条款]中的关系的主人,这就是为什么妻子说它是由丈夫映射/关联到丈夫而不是相反的方式。这意味着丈夫识别其妻子,而不是相反。

答案 1 :(得分:5)

1)Serializable界面只是一个标记。这意味着对象可以序列化,即它们可以表示为位串并从该位串恢复。

例如,您的两个类都是可序列化的,因为它们可以表示为位字符串(或常规字符串)。另一方面,表示操作系统发出的文件句柄的类无法序列化:一旦程序完成,该句柄就会消失,并且无法将其恢复。无法保证按文件名重新打开文件,因为在此期间可能已删除/移动/更改了权限。

2)序列化未实现Serializable接口的对象将导致抛出NotSerializableException

3)根据documentation

  

<强>的mappedBy
  此元素仅在关联的反向(非拥有)侧指定。

答案 2 :(得分:3)

  1. 接口Serializable有助于保持对象实例的状态。

  2. 根据jpa规范:

    “如果要通过值将实体实例作为分离对象传递(例如,通过远程接口),则实体类必须实现Serializable接口” - JSR 220 Persistence - see 2.1 Requirements on the Entity Class

  3. 根据java ee文档:

    “拥有该关系的字段。此元素仅在关联的反向(非拥有)一侧指定。” - Java EE 6 Documentation

答案 3 :(得分:0)

我只是想回答第三个问题,因为它没有完全解释。

这是你的问题:

  

为什么丈夫成员单独拥有@OnetoOne(mappedBy =&#34;妻子&#34;),但妻子成员没有@OnetoOne(mappedBy =&#34;丈夫&#34;)

首先,这里有一些问题:它应该是: @OneToOne(mappedBy="wife"),而非 Wife 。请注意,mappedBy后面应该跟wife类的属性 Husband,而不是 Wife,虽然Husband类是所有者,但Husband类名称都不是。在document of Hibernate中说:

  

mappedBy是指所有者方的关联的属性名称。

其次,要记住的一点是,在进行数据库映射时有两种关系:单向双向。我们使用单向关系,当我们只想要一个部分处理/维护这种关系时,但从另一方面来说,我们对获取这一方的数据不感兴趣。在您的示例中,如果我们只想要从HusbandWife类的单向关系,我们只想知道一个类型为Husband的对象,谁是他的妻子(通过它的getWife()方法),但我们对了解一位女士的丈夫并不感兴趣。

在这种情况下,我们可以像这样编码: (请注意,在课程Husband中,我们有Wife类型的属性,但在Wife课程中,我们具有Husband的属性型)

Husband.java:

@Entity
public class Husband implements Serializable {

   ...
   @OneToOne
   //note that @JoinColumn is necessary when mapping, 
   //and although in the table you may have columns like 
   //`ID_WIFE` in table of Husband, in Java it's not a number 
   //attribute, it's an attribute of `Wife` type.
   @JoinColumn(name="idWife")
   private Wife wife;

}

Wife.java:

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   //We can omit the attribute `husband` of `Husband` type, 
   //because we are not interested in it. Or, we don't need 
   //to map in the owned side, because it's unidirectional.

}

但是,如果我们想要建立双向关系,我们必须在所有方面进行映射,在属性拥有之前需要mappedBy

我们保持Husband方面完好无损,我们更改了Wife.java

Wife.java:

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne(fetch=FetchType.LAZY, mappedBy="wife")
   private Husband husband;


}

查看此页面:https://en.wikibooks.org/wiki/Java_Persistence/OneToOne,它以可理解的方式解释了所有内容。

第三,只是一点注意:所有者方面,通常是具有另一个表的FK的表的类。或者,我们只记得:所有者拥有它,所以它的表中也有FK。