Search This Blog

Sunday, August 18, 2013

JPA Single Table Strategy

The default inheritance mapping strategy is the single-table strategy, in which all the entities in the hierarchy are mapped to a single table. As it is the default, you can completely omit the @Inheritance annotation on the root entity (thanks to configuration by exception).
In the single table inheritance, the entire class hierarchy is represented by a single table. As the following example shows, the Three classes map to the same VET_ALL table

TABLE CREATION:

CREATE TABLE VET_ALL 
(
  VET_ID NUMBER NOT NULL 
, NAME VARCHAR2(45 BYTE) 
, QUALIFICATION VARCHAR2(45 BYTE) 
, SALARY NUMBER 
, COUNTRY VARCHAR2(45 BYTE) 
, VISITING_FEES NUMBER 
, VET_TYPE VARCHAR2(10 BYTE) 
, CONSTRAINT VET_ALL_PK PRIMARY KEY 
  (
    VET_ID 
  )
   ENABLE
);

SEQUENCES AND TRIGGERS CREATION:

CREATE SEQUENCE VET_ALL_SEQ NOCACHE;

create or replace TRIGGER VET_ALL_TRG 
BEFORE INSERT ON VET_ALL 
FOR EACH ROW 
BEGIN
    IF :NEW.VET_ID IS NULL THEN
      SELECT VET_ALL_SEQ.NEXTVAL INTO :NEW.VET_ID FROM DUAL;
    END IF;
END; 


INSERT TEST DATA:

REM INSERTING into VET_ALL
Insert into VET_ALL (VET_ID,NAME,QUALIFICATION,SALARY,COUNTRY,VISITING_FEES,VET_TYPE) values (1,'Ashitraj more','mvsc',35000,null,null,'IN_VET9');
Insert into VET_ALL (VET_ID,NAME,QUALIFICATION,SALARY,COUNTRY,VISITING_FEES,VET_TYPE) values (2,'Raj','bvsc',30000,null,null,'IN_VET');
Insert into VET_ALL (VET_ID,NAME,QUALIFICATION,SALARY,COUNTRY,VISITING_FEES,VET_TYPE) values (4,'Rakesh','mvsc',29000,null,null,'IN_VET');
Insert into VET_ALL (VET_ID,NAME,QUALIFICATION,SALARY,COUNTRY,VISITING_FEES,VET_TYPE) values (5,'John','mvsc',null,'US',450,'EXT_VET');
Insert into VET_ALL (VET_ID,NAME,QUALIFICATION,SALARY,COUNTRY,VISITING_FEES,VET_TYPE) values (3,'Steven','mvsc',null,'UK',500,'EXT_VET');

CLASS CREATION:


SingleVet Class
@Entity
@Table(name = "VET_ALL")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "VET_TYPE")
public abstract class SingleVet implements Serializable {
    
private static final long serialVersionUID = 1L;
    
@Id
@Basic(optional = false)
@Column(name = "VET_ID")
private Integer vetId;
@Column(name = "NAME")
private String name;
@Column(name = "QUALIFICATION")
private String qualification;
//generate getters, setters, toString(), hashCode(),equals()
}

SingleOutVet Class
@Entity
@DiscriminatorValue("EXT_VET")
public class SingleOutVet extends SingleVet{
    
@Column(name = "COUNTRY")
private String country;
@Column(name = "VISITING_FEES")
private Integer visitingFees;
//generate getters, setters, toString(), hashCode(),equals()
}

SingleInVet Class
@Entity
@DiscriminatorValue("IN_VET")
public class SingleInVet extends SingleVet{
 
@Column(name = "SALARY")
private Integer salary;
//generate getters, setters, toString(), hashCode(),equals()
}

JUNIT TEST CASE:

public class InheritanceJUnit {

    static EntityManagerFactory emf;
    static EntityManager em;
    static EntityTransaction trx;

    @BeforeClass
    public static void initEntityManager() throws Exception {
        emf = Persistence.createEntityManagerFactory("JavaApplicationJPAPU");
        em = emf.createEntityManager();
        trx = em.getTransaction();
    }

    @AfterClass
    public static void closeEntityManager() throws Exception {
        em.close();
        emf.close();
    }

    @Before
    public void initTransaction() throws Exception {
        trx.begin();
    }

    @After
    public void endTransaction() throws Exception {
        if (!trx.getRollbackOnly()) {
            trx.commit();
        }
    }
    
    @Test
    @Ignore
    public void testSingleStrategyInsert() {

        SingleInVet inVet = new SingleInVet();
        inVet.setName("Invet name 10");
        inVet.setQualification("invet Qualification 10");
        inVet.setSalary(1010);
        inVet.setVetId(10);
        em.persist(inVet);
        System.out.println("InHouseVet inserted");

        SingleOutVet extVet = new SingleOutVet();
        extVet.setName("extVet name 11");
        extVet.setQualification("extVet Qualification 11");
        extVet.setCountry("xy");
        extVet.setVisitingFees(1111);
        extVet.setVetId(11);
        em.persist(extVet);
        System.out.println("ExternatVet inserted");
    }

    @Test
    @Ignore
    public void testSingleStrategySelect() {
        SingleVet vet = em.find(SingleVet.class, 10);
        assertNotNull(vet);

        if (vet instanceof SingleOutVet) {
            SingleOutVet singleOutVet = (SingleOutVet) vet;
            System.out.println(singleOutVet);
        } else if (vet instanceof SingleInVet) {
            SingleInVet singleInVet = (SingleInVet) vet;
            System.out.println(singleInVet);
        } else {
            System.out.println("ERROR in Type");
        }

        SingleVet vet2 = em.find(SingleVet.class, 11);
        assertNotNull(vet2);

        if (vet2 instanceof SingleOutVet) {
            SingleOutVet singleOutVet = (SingleOutVet) vet2;
            System.out.println(singleOutVet);
        } else if (vet2 instanceof SingleInVet) {
            SingleInVet singleInVet = (SingleInVet) vet2;
            System.out.println(singleInVet);
        } else {
            System.out.println("ERROR in Type");
        }

    }

    @Test
    @Ignore
    public void testSingleStrategyUpdate() {

        SingleVet vet = em.find(SingleVet.class, 10);
        assertNotNull(vet);

        if (vet instanceof SingleOutVet) {
            SingleOutVet SingleOutVet = (SingleOutVet) vet;
            SingleOutVet.setName("extVet Qualification 11 updated");
            SingleOutVet.setVisitingFees(101010);
            em.merge(SingleOutVet);
            System.out.println(SingleOutVet);
        } else if (vet instanceof SingleInVet) {
            SingleInVet SingleInVet = (SingleInVet) vet;
            SingleInVet.setName("Invet name 10 updated");
            SingleInVet.setSalary(1010);
            em.merge(SingleInVet);
            System.out.println(SingleInVet);
        } else {
            System.out.println("ERROR in Type");
        }

        SingleVet vet2 = em.find(SingleVet.class, 11);
        assertNotNull(vet2);

        if (vet2 instanceof SingleOutVet) {
            SingleOutVet SingleOutVet = (SingleOutVet) vet2;
            SingleOutVet.setName("extVet Qualification 11 updated");
            SingleOutVet.setVisitingFees(111111);
            em.merge(SingleOutVet);
            System.out.println(SingleOutVet);
        } else if (vet2 instanceof SingleInVet) {
            SingleInVet SingleInVet = (SingleInVet) vet2;
            SingleInVet.setName("Invet name 11 updated");
            SingleInVet.setSalary(1111);
            em.merge(SingleInVet);
            System.out.println(SingleInVet);
        } else {
            System.out.println("ERROR in Type");
        }
    }

    @Test
    @Ignore
    public void testSingleStrategyDelete() {

        SingleVet vet = em.find(SingleVet.class, 10);
        assertNotNull(vet);
        em.remove(vet);
        System.out.println("InHouseVet 10 : deleteds");

        SingleVet vet2 = em.find(SingleVet.class, 11);
        assertNotNull(vet2);
        if (vet2 instanceof SingleOutVet) {
            SingleOutVet singleOutVet = (SingleOutVet) vet2;
            em.remove(singleOutVet);
            System.out.println("ExternatVet 11 : deleted");
        } else if (vet2 instanceof SingleInVet) {
            SingleInVet singleInVet = (SingleInVet) vet2;
            em.remove(singleInVet);
            System.out.println("InHouseVet 11 : deleteds");
        } else {
            System.out.println("ERROR in Type");
        }
    }

}

No comments: