Skip to content

One to One


layout: default title: @OneToOne


Use the @OneToOne annotation to describe a one-to-one relationship.

  • Annotate the defining field in the owning entity to specify mapping details.

  • The owning entity is the one whose corresponding database table contains the foreign key which models the relationship.

  • Use the @JoinColumn annotation to specify the foreign key column name.

Customer SQL Table

@Entity
public class Customer {
     // ...
     @OneToOne
     @JoinColumn(name="address_id")
     private Address address;
     // ...
}
  • In the non-owning entity of a bi-directional relationship, add the @OneToOne annotation above the field that references the owning entity.

  • Use the mappedBy element on the @OneToOne annotation to specify the defining field in the owning entity.

@Entity
public class Address {
     // ...
     @OneToOne(mappedBy="address")
     private Customer customer;
     // ...
}

Digging Deeper

One To One

  • For a uni-directional relationship, omit the second @OneToOne annotation (with the mappedBy element), and the field it decorates.
 You only need a field and mapping in the owning entity of a uni-directional relationship.

Drill

  1. Delete the field and the gets/sets for addressId from your Customer class.

    @Column(name="address_id")
    public int addressId;
    
    This will break the CustomerRelationshipClient due to the fact that the gets/sets we are calling no longer exist. Because this was just a demo, it's not a problem. Comment out the main to get rid of the errors.

  2. Create a uni-directional, one-to-one relationship between your Customer and Address entities.

  3. First, in Customer add a field of type Address annotated with @OneToOne and @JoinColumn.

    Here is the customer table for you to reference:

    +-------------+----------------------+------+-----+-------------------+-----------------------------+
    | Field       | Type                 | Null | Key | Default           | Extra                       |
    +-------------+----------------------+------+-----+-------------------+-----------------------------+
    | id          | int(10) unsigned     | NO   | PRI | NULL              | auto_increment              |
    | store_id    | smallint(5) unsigned | NO   | MUL | NULL              |                             |
    | first_name  | varchar(45)          | NO   |     | NULL              |                             |
    | last_name   | varchar(45)          | NO   | MUL | NULL              |                             |
    | email       | varchar(50)          | YES  |     | NULL              |                             |
    | address_id  | int(10) unsigned     | NO   | MUL | NULL              |                             |
    | active      | tinyint(1)           | NO   |     | 1                 |                             |
    | create_date | datetime             | NO   |     | NULL              |                             |
    | last_update | timestamp            | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
    +-------------+----------------------+------+-----+-------------------+-----------------------------+
    
  4. Also, replace the get/set methods with new versions.

  5. Because this is a uni-directional relationship, the Address entity remains unchanged.

  6. Update CustomerTest so that it tests your new relationship.

  @Test
  public void test_customer_to_address_association() {
     Customer cust = em.find(Customer.class, 2);
     Address address = cust.getAddress();
     assertEquals("1121 Loja Avenue", address.getStreet());
     assertEquals("", address.getStreet2());
     assertEquals("San Bernardino", address.getCity());
     assertEquals("17886", address.getPostalCode());
  }

Prev -- Up -- Next