Hibernate (or JPA) - Using "mappedBy" attribute of mapping annotations(like @OneToOne, @OneToMany, @ManyToMany)

Using "mappedBy" attribute of mapping annotations(like @OneToOne, @OneToMany, @ManyToMany) for bi-directional relationship. This attribute allows you to refer the associated entities from both sides. If "X" has association with "Y" then you can get X from Y and Y from X.

For example, If you have "Book" entity and "Author" entity those are associated to each other in the way that Book has a Author and Author associated with a Book.
Now if you retrieve the Book Object from hibernate session, then you can get the Author entity from Book entity. Or if you get the Author entity then you can get the Book entity from Author entity.
So you require the bidirectional navigation relationships between Book and Author entities.

This is achieved in the Hibernate using the  @OneToOne relationship provided that child entity must have property type of parent and marked with annotation @OneToOne(mappedBy="parent") where parent is the Owner entity of this child entity.


package entity;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Book")
public class Book {
    private int id;
    private String title;
    private String content;
    private Author author;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
    
    @OneToOne(cascade=CascadeType.ALL)
    public Author getAuthor() {
        return author;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book [id=" + id + ", title=" + title + ", content=" + content
                + ", author=" + author.getId() + "]";
    }
    
}


package entity;

import javax.persistence.*;

@Entity
@Table(name = "Author")
public class Author {
    private int id;
    private String name;
    private String email;
    private long phone;
    private Book book;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public long getPhone() {
        return phone;
    }

    public void setPhone(long phone) {
        this.phone = phone;
    }
    @OneToOne(mappedBy="author")
    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    @Override
    public String toString() {
        return "Author [id=" + id + ", name=" + name + ", email=" + email
                + ", phone=" + phone + ", book=" + book.getId() + "]";
    }
    
}


Testing classes

Inserting records


import java.util.ArrayList;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import entity.Author;
import entity.Book;


public class Insert {
    public static void main(String[] args) {
        Configuration cfg=new Configuration();
        SessionFactory sf=cfg.configure("hibernate.cfg.xml").buildSessionFactory();
        Session session = sf.openSession();
        
        Author author=new Author();
        author.setEmail("author@gmail.com");
        author.setName("name");
        author.setPhone(543653465L);
        
        Book book1=new Book();
        book1.setAuthor(author);
        book1.setContent("re  td e sdf asdfasdfasd f");
        book1.setTitle("java");
        
        session.beginTransaction();
        session.save(book1);
        session.getTransaction().commit();
        
    }
}

Retrieving Records

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import entity.Author;
import entity.Book;

public class update {
    public static void main(String[] args) {
        Configuration cfg=new Configuration();
        SessionFactory sf=cfg.configure("hibernate.cfg.xml").buildSessionFactory();
        Session session = sf.openSession();
        session.beginTransaction();
        
        //Book book = (Book) session.get(Book.class, 2);
        //System.out.println(book.getAuthor());
        
        Author author = (Author) session.get(Author.class3);
        System.out.println(author.getBook());
        //book.getAuthor().setName("Test Author");
        //session.getTransaction().commit();
        
    }
}

hibernate configuration file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
        <property name="connection.username">hemraj</property>
        <property name="connection.password">hemraj</property>
        <property name="dialect">org.hibernate.dialect.OracleDialect</property>
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <mapping class="entity.Library"/>
        <mapping class="entity.Book"/>
        <mapping class="entity.Author"/>
    </session-factory>
</hibernate-configuration>

3 comments:

Anonymous said...

Very useful example. Thank you so much. It saved my one day since I had been struggling to find parent entity of child entity.

Ranjeet Singh said...

Good explanation of mappedBy attribute. Thank u

Naryck said...

Very good explanation! I'd even say it's great! Thanks.

Popular Posts