Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 25

V.

Advanced Mappings

Prof. dr Angelina Njeguš

Java Persistence API


Understanding the model Inheritance in Databases
• Single table:
– This strategy means that all the class hierarchy is
stored in a single table in the database. The top
level columns can allow nulls but all the lower
level columns must allow nulls.
– There is an additional column (in the following
example: PersonType) which is the discriminator
– it holds a value indicating the level in the
hierarchy to which the record matches.
– The lower level columns do not have their own
ID!
– Single table inheritance is the simplest and typically
the best performing and best solution.
An example of single table

Java Persistence API


Table per Subclass
 This strategy means that each level in the class hierarchy is represented in a table in
the database.
 The top level table (Person) contains the columns that are common to all levels and
as we go down in the hierarchy, we get only the additional columns for the specific
level.
 The root table contains the discriminator columns, for joining with the appropriate
table when selecting rows.
 The lower level columns have IDs!

Java Persistence API


An Example
 Each table in the hierarchy must
also store the object's id
(primary key), which
is only defined in the root class.
 All classes in the hierarchy must
share the same id attribute.
 A discriminator column is used
to determine which class the
particular row belongs to, each
class in the hierarchy defines its
own unique discriminator value.

Java Persistence API


Table per Concrete Class
• Not so used!
Mapped Superclasses
 A mapped superclass provides a convenient class on which to store shared state and
behavior that entities can inherit from.
 It is itself not a persistent class and cannot act in the capacity of an entity.
 It cannot be queried over
 Annotations such as @Table are not permitted on mapped superclasses because the
state defined in them applies only to its entity subclasses.
 If you are not sure whether to make a class an entity or a mapped superclass, then
you need only ask yourself if you will ever need to query across or access an instance
that is only exposed as an instance of that mapped class.
 If you answer yes to any variant of that question, then you should probably make it a
first-class entity.

Java Persistence API


@MappedSuperclass
• The CompanyEmployee class can be
mapped superclass instead of an entity.
• It defines shared state, but perhaps we
have no reason to query over it.
@MappedSuperclass annotation
@Entity @MappedSuperclass
public class Employee { public abstract class CompanyEmployee extends Employee {
@Id private int id; private int vacation;
private String name; // ...
@Temporal(TemporalType.DATE) }
@Column(name="S_DATE") @Entity
private Date startDate; public class FullTimeEmployee extends CompanyEmployee {
// ... private long salary;
} private long pension;
@Entity // ...
public class ContractEmployee extends Employee { }
@Column(name="D_RATE") @Entity
private int dailyRate; public class PartTimeEmployee extends CompanyEmployee {
private int term; @Column(name="H_RATE")
// ... private float hourlyRate;
} // ...
}
Inheritance Strategies
 JPA is a library which is released with java specification. Therefore, it supports all
object oriented concepts for entity persistence.
 Inheritance is the core concept of object oriented language, therefore we can use
inheritance relationships or strategies between entities.
 JPA support three types of inheritance strategies
– SINGLE_TABLE,
– JOINED_TABLE, and
– TABLE_PER_CONCRETE_CLASS.
 The use of two of them is fairly widespread, while the third is less common and not
required to be supported.
 The root entity class must signify the inheritance hierarchy by being annotated with
the @Inheritance annotation.
Java Persistence API
Single-Table Strategy
• A single table contains a superset of all the possible
state in any of the entity classes.
• The id is located in the root Employee entity class
and is shared by the rest of the persistence classes.
• All the persistent entities in an inheritance tree must
use the same type of identifier.
• To specify the single-table strategy for the
inheritance hierarchy, the root entity class is
annotated with the @Inheritance annotation with its
strategy set to SINGLE_TABLE:
Nullable attributes (columns) in subclasses
• The table must contain enough columns to store all the
state in all the classes.
• An individual row stores the state of an entity instance of
a concrete entity type, which would normally imply that
there would be some columns left unfilled in every row.
• Threfore, the columns mapped to concrete subclass state
should be nullable.

 an extra column named EMP_TYPE


is required when using a single table
and it is called a discriminator
column
Discriminator Column
 A discriminator column is mapped using the @DiscriminatorColumn annotation in
conjunction with the @Inheritance annotation.
 The name element of this annotation specifies the name of the column that should
be used as the discriminator column, and if not specified will be defaulted to a
column named “DTYPE”.
 A discriminatorType element dictates the type of the discriminator column.
 If the discriminatorType element is not specified, then the default type of STRING will
be assumed.

Java Persistence API


Discriminator Value @Entity
@Table(name="EMPLOYEE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE )
• Every row in the table will have a value
@DiscriminatorColumn(name="EMP_TYPE")
in the discriminator column called a public abstract class Employee implements Serializable { ... }
discriminator value, or a class indicator,
to indicate the type of entity that is @Entity
stored in that row. public class ContractEmployee extends Employee { ... }
• Every concrete entity in the inheritance @MappedSuperclass
hierarchy, therefore, needs a public abstract class CompanyEmployee extends Employee { ... }
discriminator value specific to that
entity type so that the provider can @Entity
process or assign the correct entity @DiscriminatorValue("FTEmp")
type when it loads and stores the row. public class FullTimeEmployee extends CompanyEmployee { ... }

• The way this is done is to use a @Entity


@DiscriminatorValue annotation on @DiscriminatorValue(“PTEmp”)
each concrete entity class. public class PartTimeEmployee extends CompanyEmployee { ... }
Sample of single-table inheritance data

Java Persistence API


SINGLE_TABLE

Java Persistence API


Staff.java
@Entity
@Table
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")

public class Staff implements Serializable {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int sid;
private String sname;

Java Persistence API


TeachingStaff.java 
@Entity
@DiscriminatorValue(value="TS")
public class TeachingStaff extends Staff {

private String qualification;


private String subjectexpertise;

Java Persistence API


NonTeachingStaff.java 
@Entity
@DiscriminatorValue(value="NS")

public class NonTeachingStaff extends Staff {


private String areaexpertise;

Java Persistence API


Service (main) class: SaveClient.java 
public class SaveClient {

public static void main( String[ ] args ) {

EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );


EntityManager entitymanager = emfactory.createEntityManager( );
entitymanager.getTransaction( ).begin( );

//Teaching staff entity


TeachingStaff ts1=new TeachingStaff(1,"Gopal","MSc MEd","Maths");
TeachingStaff ts2=new TeachingStaff(2, "Manisha", "BSc BEd", "English");

//Non-Teaching Staff entity


NonTeachingStaff nts1=new NonTeachingStaff(3, "Satish", "Accounts");
NonTeachingStaff nts2=new NonTeachingStaff(4, "Krishna", "Office Admin");

//storing all entities


entitymanager.persist(ts1);
entitymanager.persist(ts2);
entitymanager.persist(nts1);
entitymanager.persist(nts2);

entitymanager.getTransaction().commit();

entitymanager.close();
emfactory.close();
}
} Java Persistence API
Joined table strategy
 Joined table strategy is to share the referenced column which contains unique values
to join the table and make easy transactions.

STAFF
@Entity
@Table • staff_ID
@Inheritance(strategy = InheritanceType.JOINED) • Sname

public class Staff implements Serializable {


TEACHING STAFF NON—TEACHING
@Id STAFF
@GeneratedValue( strategy = GenerationType.AUTO ) • staff_ID • staff_ID
private int sid; • Qualification • AreaExpertise
• SubjectExpertise
private String sname;

Java Persistence API


@Entity
@PrimaryKeyJoinColumn(referencedColumnName="staff_ID")

public class TeachingStaff extends Staff {


private String qualification;
private String subjectexpertise;

TEACHING STAFF

• staff_ID
• Qualification
• SubjectExpertise

Java Persistence API


@Entity
@PrimaryKeyJoinColumn(referencedColumnName="staff_ID")

public class NonTeachingStaff extends Staff {


private String areaexpertise;

public NonTeachingStaff(int staff_ID, String sname, String areaexpertise ) {


super(staf_ID, sname);
this.areaexpertise = areaexpertise;
NON—TEACHING
} STAFF
• staff_ID
• AreaExpertise

Java Persistence API


Service (main) class: SaveClient.java
 Create a class named SaveClient.java under the given package to store Staff,
TeachingStaff, and NonTeachingStaff class fields.
public class SaveClient {
public static void main( String[ ] args ) {
EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
EntityManager entitymanager = emfactory.createEntityManager( );
entitymanager.getTransaction( ).begin( );

//Teaching staff entity


TeachingStaff ts1 = new TeachingStaff(1,"Gopal","MSc MEd","Maths");
TeachingStaff ts2 = new TeachingStaff(2, "Manisha", "BSc BEd", "English");

//Non-Teaching Staff entity


NonTeachingStaff nts1 = new NonTeachingStaff(3, "Satish", "Accounts");
NonTeachingStaff nts2 = new NonTeachingStaff(4, "Krishna", "Office Admin");

//storing all entities


entitymanager.persist(ts1);
entitymanager.persist(ts2);
entitymanager.persist(nts1);
entitymanager.persist(nts2);

entitymanager.getTransaction().commit();
entitymanager.close();
Java Persistence API
emfactory.close();
Exercise
 If we have the following model (as on the right figure):
– Which diagram represents joined_table: (a) or (b)?

(a) (b)
=

Java Persistence API

You might also like