7
@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. What is Serializable in broad term?
  2. Why does a class implements Serializable interface?
  3. Why does the husband member alone have @OnetoOne(mappedBy ="Wife"), but the wife member does not have @OnetoOne(mappedBy="husband")
Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
John Cooper
  • 7,343
  • 31
  • 80
  • 100

4 Answers4

13
  1. Serialization, in broad terms, is the way Java provides developers to persist the state of any object to a persistent store.

  2. If a developer wants that for some reason instance of his coded class should be persisted to a backing store, then the class needs to be declared as implementing Serializable.

  3. The above code represents a One to One relationship between a Husband and a Wife. Which basically means that each wife is related to one husband and each husband is related to one wife. :-) Also in the above relationship, the Husband is the master of the relationship [in Entity-Relationship terms] and that is why Wife says that it is mapped/associated to Husband by the Husband and not the other way around. Which means Husband identifies its wife and not the other way around.

Swaranga Sarma
  • 13,055
  • 19
  • 60
  • 93
7

1) The Serializable interface is just a marker. It means that objects can be serialized, i.e. they can be represented as a bit string and restored from that bit string.

For example, both of your classes are serializable because they can be represented as a bit string (or regular string). On the other hand, a class that represents a file handle given out by the operating system can not be serialized: As soon as the program is finished, that handle is gone, and there is no way to get it back. Reopening the file by file name is not guaranteed to work, since it may have been deleted/moved/changed permissions in the meantime.

2) Serializing objects that don't implement the Serializable interface will result in a NotSerializableException being thrown.

3) According to the documentation:

mappedBy
This element is only specified on the inverse (non-owning) side of the association.

phihag
  • 278,196
  • 72
  • 453
  • 469
3
  1. The interface Serializable helps to persist the state of an object instance.

  2. According to the jpa specification:

    "If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface" - JSR 220 Persistence - see 2.1 Requirements on the Entity Class

  3. According to the java ee documentation:

    "The field that owns the relationship. This element is only specified on the inverse (non-owning) side of the association." - Java EE 6 Documentation

Robin
  • 8,162
  • 7
  • 56
  • 101
1

I just want to answer the third question because it's not fully explained.

Here is your question:

Why does the husband member alone have @OnetoOne(mappedBy="Wife"), but the wife member does not have @OnetoOne(mappedBy="husband")

First, there is something wrong here: it should be: @OneToOne(mappedBy="wife"), not Wife. Note that mappedBy should be followed by the attribute wife of the Husband class, not the class Wife, neither the Husband class name, although the Husband class is the owner. In the document of Hibernate is said:

mappedBy refers to the property name of the association on the owner side.

Second, one thing to have in mind is, there are two kinds of relationship when we do the database mapping: unidirectional and bidirectional. We use unidirectional relationship, when we only want one part handle/maintain this relationship, but from the other side, we are not interested in getting the data of this side. In your example, if we just want an unidirectional relationship from Husband to Wife class, we only want to know, by having an object of type Husband, who is his wife(by its getWife() method), but we are not interested in knowing one lady's husband.

Under this circumstance, we can code like this: (note that in class Husband we have attribute of Wife type, but in Wife class we don't have attribute of Husband type)

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.

}

But, if we want to have an bidirectional relationship, we have to map in both side and in the owned side, mappedBy is needed before the attribute owned.

We remain the Husband side intact, and we change the 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;


}

Check this page: https://en.wikibooks.org/wiki/Java_Persistence/OneToOne, it explains it all in an understandable way.

Third, just a little note: the owner side, is commonly the class of a table with a FK of another table. Or, we just remember: the owner owns it all, so it also has the FK in its table.

WesternGun
  • 11,303
  • 6
  • 88
  • 157