Mapping a Single Entity to Multiple Tables in JPA

1. Introduction

JPA makes dealing with relational database models from our Java applications less painful. Things are simple when we map every table to a single entity class. But, sometimes we have reasons to model our entities and tables differently

We can create a single entity specifying that we have columns in different tables using the @SecondaryTable annotation:

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "suppliers")
@SecondaryTable(name = "suppliers_address", pkJoinColumns = @PrimaryKeyJoinColumn(name = "suppliers_id"))
public class SuppliersModel implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length = 30)
    private String suppliersName;

    @Column(length = 30)
    private String suppliersContact;

    @Column(length = 30)
    private String suppliersMobile;

    @Column(length = 30)
    private String suppliersEmail;

    @Column(length = 30)
    private String suppliersFax;

    @Column(length = 30)
    private String suppliersArea;

    @Column(length = 30)
    private String suppliersOpeningBalance;

    @Column(length = 30)
    private String suppliersCreditPeriod;

    @Column(length = 1)
    private boolean suppliersOrderAutomatically;

    @Column(length = 30)
    private String suppliersCSTNo;

    @Column(length = 30)
    private String suppliersGSTNo;

    @Column(length = 30)
    private String suppliersVATNo;

    @Column(length = 30)
    private String suppliersPANNo;

    @Column(length = 30)
    private String suppliersLBTNo;

    @Column(table = "suppliers_address", length = 50 )
    private String suppliersAddLine1;

    @Column(table = "suppliers_address", length = 50)
    private String suppliersAddLine2;

    @Column(table = "suppliers_address", length = 50)
    private String suppliersAddLine3;

    @Column(table = "suppliers_address", length = 30)
    private String suppliersAddCountry;

    @Column(table = "suppliers_address", length = 30)
    private String suppliersAddState;

}

Following query will be executed in background (You can check in Spring boot logs):

create table suppliers (id int8 generated by default as identity, suppliers_area varchar(30), supplierscstno varchar(30), suppliers_contact varchar(30), suppliers_credit_period varchar(30), suppliers_email varchar(30), suppliers_fax varchar(30), suppliersgstno varchar(30), supplierslbtno varchar(30), suppliers_mobile varchar(30), suppliers_name varchar(30), suppliers_opening_balance varchar(30), suppliers_order_automatically boolean, supplierspanno varchar(30), suppliersvatno varchar(30), primary key (id))

create table suppliers_address (suppliers_add_country varchar(30), suppliers_add_line1 varchar(50), suppliers_add_line2 varchar(50), suppliers_add_line3 varchar(50), suppliers_add_state varchar(30), suppliers_id int8 not null, primary key (suppliers_id))

alter table if exists suppliers_address add constraint FK3lw584uqe8x8d1cc4rye0i2mj foreign key (suppliers_id) references suppliers

It’s a similar approach to what we saw using @OneToOne. However, it has a couple of advantages:

  • JPA manages the two tables together for us, so we can be sure that there will be a row for each meal in both tables
  • Also, the code is a bit simpler, since we need less configuration

Nevertheless, this one-to-one like solution works only when the two tables have matching ids.

 

%d bloggers like this: