Unidirectional @OneToOne primary key association
Today I want to show you an example of unidirectional one to one association using primary key. It can be a little bit difficult for beginners to setup such association but I will try my best to explain all aspects in a clear way. For this tutorial I choose MySQL as a database, also I will use Hibernate and JPA annotations.
Firstly, I need two tables in the DB with a one to one relationship. Tables are pretty primitive, because the tutorial must be as simple as possible. The first table is “authors” and the second one is “biographies“. Primary key from the “authors” table is a shared primary key, so the “biographies” table has a foreign key linked to the “id” column of the “authors” table. Reading all this can be confused, so let’s give a look at the tables scheme.
The illustration of the tables are good but below I will provide a code for the tables creation:
CREATE TABLE `authors` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(30) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `biographies` ( `author_id` int(6) NOT NULL, `information` varchar(100) NOT NULL, KEY `author_bio` (`author_id`), CONSTRAINT `author_bio` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now it’s time to create POJOs which will represent our tables from the database. The first will be a Biography class, because it doesn’t require any other previously created class.
import javax.persistence.*; @Entity @Table(name="biographies") public class Biography { @Id @Column(name="author_id") private Integer authorId; private String information; public Integer getAuthorId() { return authorId; } public void setAuthorId(Integer authorId) { this.authorId = authorId; } public String getInformation() { return information; } public void setInformation(String information) { this.information = information; } }
I can’t underline something special in the Biography class. Everything is obvious. Let’s move on, the next class is the Author’s one.
import javax.persistence.*; @Entity @Table(name="authors") public class Author { @Id @GeneratedValue private Integer id; private String name; @OneToOne(cascade=CascadeType.ALL) @PrimaryKeyJoinColumn private Biography biography; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Biography getBiography() { return biography; } public void setBiography(Biography biography) { this.biography = biography; } }
Here I need to stop and say several important things:
- Author class is an owning side of association (Unidirectional associations doesn’t have inverse side). Owning side is determined by existence of primary key.
- Unidirectional association implies existence of reference just in one class (In our case it’s @OneToONe annotation in Author class).
- The @PrimaryKeyJoinColumn annotation specifies the primary key column that is used as a foreign key to join to another table.
After so serious conversation it’s time to test the code in action. I will omit Hibernate configuration etc since it was discussed earlier.
... public static void main(String[] args) { SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); Author author = new Author(); author.setName("Jack London"); session.persist(author); Biography biography = new Biography(); biography.setInformation("Jack London was an American author..."); biography.setAuthorId(author.getId()); author.setBiography(biography); session.save(author); session.getTransaction().commit(); session.close(); } ...
Notice that firstly I have persisted the author’s object to get its id for the further usage. When I started working with the biography object I set to it the id of already persisted author object. Then I added the biography object to the author, saved the author object and finally I committed the transaction.
You can see the results of the code execution in the database. Just browse appropriate tables and watch the record about Jack London. Thats all what I want to say about unidirectional one to one associations in Hibernate.