à1.
Association Relation Ship:
àBy using this ORM-mapping
model we can resolve/solve the
"Association Impedance mismatch"
problem.
àAssociation is 3-types
1.
Association[No
owner and Life time is Independent]
2.
Aggregation[Owner
and Life time is Independent]
3.
Composition[Owner
and Life time is dependent]
àAssociation and
Aggregation is looks like same hence we will considered these are same in
relational model hence in ORM we can map Association Relation in 2-ways.
1.
Association
Mapping Model(Association or Aggregation)
2.
Component Mapping
Model(Composition)
1. Association Mapping Model (Association or
Aggregation):
Ex:
class Person {
private int personId;
private String firstNm;
private String lastNm;
private String gender;
private int age;
private Address address;
}
class Address {
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private int zip;
private String country;
}
à By looking at the classes we cannot identify the cardinality between
the class related tables. That means on-to-one or one-to-many or many-many we
cannot tell easily. In data modelling terms, cardinality means how one table
relates to another.
àWhen we try to persist
the Person along with Person Address also need to persist, that means how can
we persist the associated obj in to the DB is one of the Impedance Miss match
so ORM given a solution called as Association mapping Model.
àIf we persist Person
along with person Address also need to persist that may be either
unidirectional or bi-directional.
Note: See Excel-Sheets
àAssociation Mapping Model
A). Unidirectional Mappings:
1.1 One-To-One (Using FK as Unique Constraint/Many
to One)
class Person {
private int personId;
private String firstNm;
private String lastNm;
private String gender;
private int age;
private Address address;
}
class Address {
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private int zip;
private String country;
}
PERSON
|
ADDRESS
|
|||||
PK
|
PERSON_ID
|
PK
|
ADDRESS_ID
|
|||
FIRST_NM
|
ADDRESS_LINE1
|
|||||
LAST_NM
|
ADDRESS_LINE2
|
|||||
GENDER
|
CITY
|
|||||
AGE
|
STATE
|
|||||
FK,UNQ
|
ADDRESS_ID
|
ZIP
|
||||
COUNTRY
|
àPerson.hbm.xml:
<hibernate-mapping>
<class
name="Person" table="PERSON">
<id
name="personId" column="PERSON_ID" />
<property name="firtstName"
column="FIRST_NM" />
<property
name="lastname" column="LAST_NM" />
<property
name="gender" column="GENDER" />
<property
name="age" column="AGE" />
<many-to-one
name="address" column="ADDRESS_ID"
class="Address"/>
</class>
</hibernate-mapping>
àAddress.hbm.xml:
<hibernate-mapping>
<class
name="Address" table="ADDRESS">
<id
name="addressId" column="ADDRESS_ID" />
------
</class>
</hibernate-mapping>
Explanation:
àAttribute
"address" is not a primitive attribute hence we should not write the
<property> tag.
àIn order to get or find
the Person Address we need to join the FK column ADDRESS_ID (or we can take
ADDRESS_ID as P_ADDRESS_ID) of PERSON table with PK column ADDRESS_ID of
ADDRESS table.
àAlways FK in a table
represents many relationship. Here ADDRESS_ID as a FK in the PERSON table
represents the many side relationship and if we make this as UNIQUE then it
becomes one-to-one, so we need to tell the hibernate there is a FK column
ADDRESS_ID which is there in the PERSON table is joins with the PK column
ADDRESS_ID of ADDRESS table that’s why we need to we need to write <many-to-one>.
àThat means we need to
tell the hibernate there is an FK column ADDRESS_ID in the PERSON table which
has to be join with PK column ADDRESS_ID of ADDESS table which is represented
by the Address class as attribute "address" to derive the data of
Address class.
<many-to-one name="address"
column="ADDRESS_ID" class="Address"/>
àIn the above tag column="ADDRESS_ID"
represents FK column in the PERSON table.
àUsing
class="Address" hibernate identifies ADDRESS table and gets the PK
column for joining.
Note:
àHere if we didn’t specify
the class="Address" then hibernate will identifies PK column of
ADDRESS table using attribute name="address" which is specified in
the <many-to-one> tag.
<many-to-one name="address"
column="ADDRESS_ID"/>
Ex: 2
class Employee {
private int employeeId;
private String firstNm;
private String lastNm;
private String gender;
private int age;
private float salary;
private PFAccount pfAccount;
}
class PFAccount {
private int pfAccountNo;
private Date openedDate;
private float balance;
}
#1:
EMPLOYEE
|
PF_ACCOUNT
|
|||
PK
|
EMPLOYEE_ID
|
PK
|
PF_ACCOUNT_NO
|
|
FIRST_NM
|
OPENED_DT
|
|||
LAST_NM
|
BALANCE
|
|||
GENDER
|
||||
AGE
|
||||
SALARY
|
||||
FK,UNQ
|
PF_ACCOUNT_NO
|
<many-to-one name="pfAccount" column="PF-ACCOUNT_NO"
class="PFAccount" unique="true" not-null="true"/>
(Or)
<many-to-one name="pfAccount"
column="PF-ACCOUNT_NO" unique="true"
not-null="true"/>
#2:
EMPLOYEE
|
PF_ACCOUNT
|
|||
PK
|
EMPLOYEE_ID
|
PK
|
PF_ACCOUNT_NO
|
|
FIRST_NM
|
OPENED_DT
|
|||
LAST_NM
|
BALANCE
|
|||
GENDER
|
||||
AGE
|
||||
SALARY
|
||||
FK,UNQ
|
EPF_ACCOUNT_NO
|
<many-to-one name="pfAccount"
column="EPF-ACCOUNT_NO" class="PFAccount"
unique="true" not-null="true"/>
(Or)
<many-to-one name="pfAccount"
column="EPF-ACCOUNT_NO" unique="true"
not-null="true"/>
Note:
pfAccount = new PFAccount();
pfAccount.setOpenedDate(new Date());
pfAccount.setBalance(18212);
employee = new Employee();
employee.setFirstName("DB");
employee.setLastName("REDDY");
employee.setGender("M");
employee.setSalary(192122);
employee.setAge(24);
employee.setPfAccount(pfAccount);
session.save(employee);
àWhile saving the employee
1st we need save PFAccount and then we need to save Empoyee
otherwise we will get TransientPropertyValueException: Not-null property
references a transient value - transient instance must be saved before current
operation: com.oto.entities.Employee.pfAccount àcom.oto.entities.PFAccount.
àHence we need to save 1st
PFAccount and then we need to save Empoyee.
session.save(pfAccount);
session.save(employee);
#1
<many-to-one name="pfAccount"
column="EPF-ACCOUNT_NO" unique="true"
not-null="true"/>
Employee employee = (Employee) session.get(Employee.class, id);
àBy default hibernate
generates 2-select queries to fetch the Employee and PFAccount data from the
DB.
#2
<many-to-one name="pfAccount"
column="EPF_ACCOUNT_NO"
unique="true"
not-null="true" fetch="join"/>
àHibernate generates
1-select query to fetch the Employee and PFAccount data from the DB bcz we
specified fetch="join" to fetch the data in a single query.
Note:
We can even specify in the cfg.xml for globally join, left-outer-join,
and inner-join etc tags in the property tag.
àAnnotations:
What is the inverse equivalent attribute in annotations in
bidirectional relation?
Answer: "inverse" in configurationà "mappedBy" in Annotations
@OneToOne(mappedBy="pfAccounts")
àSome more Examples
for One-To-One:
àSim Subscriber and Customer.
CUSTOMER
|
SUBSCRIBER
|
|||
PK
|
CSTOMER_ID
|
PK
|
SUBSCRIBER_ID
|
|
FIRST_NM
|
SUBSCRIPTION_DT
|
|||
LAST_NM
|
ACTIVATION_DT
|
|||
DOB
|
MOBILE
|
|||
GENDER
|
SECURITY_DEPOSIT
|
|||
FK,UNQ
|
SUB_CUSTOMER_ID
|
Every Customer may not be a Sim subscriber but every subscriber is a
customer. Hence CUSTOMER_ID should a FK for SUBCRIBER table.
1.2 One-To-One (Using PK as FK):
àEmployee Offer Letter and
Payroll
EMPLOYEMENT_OFFER
|
EMPLOYEMENT_OFFERED_PAYROLL
|
|||
PK
|
OFFER_ID
|
FK,PK
|
OFFER_ID
|
|
OFFER_DT
|
BASIC
|
|||
CANDIDATE_NM
|
HRA
|
|||
MOBILE
|
PF
|
|||
DESIGNATION
|
MEDICA_CLAIM_AMOUNT
|
|||
DATE_OF_JOIN
|
LTA
|
|||
CTC
|
SPECIAL_ALLOWANCES
|
àAnnotations:
àWhere did you
used load() in your project
House house = (House) session.load(House.class, 3);
layout = new Layout();
layout.setSurveyNo("S1221");
layout.setPlotNo("P29292");
layout.setArea(1122);
layout.setUnitsType("YARDS");
layout.setFacing("EAST");
layout.setHouse(house);
session.save(layout);
Here
we are using load() method is used to save the performance bcz load is lazy
initializer and it takes this from the cache and will not goes to the DB so
that to link only it will not queries.
B). Bi-Directional Mappings:
1.3 One-To-One (Using FK as Unique Constraint/Many
to One)
Annotations:
1.4 One-To-One (Using PK as FK)
Annotations:
2. One-To-many (Unidirectional):
àIn order to specify the
many relationship we need collection in entity class that may be Set, List or
Map and based on our requirement
we will use corresponding collection.
àOne-To-many
Using Set:
Explanation:
àAttribute "address"
is not a primitive attribute hence we should not write the <property>
tag.
àHere key represents the
PK of PERSON table and column="ADDRS_PERSON_ID" represents FK of the
ADDRESS table.
àHere we are writing
<one-to-many> tag bcz many-side relation is in the ADDRESS table and many
addresses belongs to one PERSON hence it is <one-to-many> and FK relation
is specified in <key> tag.
àHere while we are
retrieving the person it will do left-outer join with Person bcz Person data
always need to come even though Address is not there for that person.
à<set> is collection
which cannot allows the duplicates and it will not detects the duplicates
unless until we overrides the equals() and hashCode() of Person and Address
class.
Examples:
àEx: 1
Property and approval (One Property will have many Approvals and
Approvals belongs to one Property)
àEx: 2
Property and Bill (One Property will have many Bills and a Bill
belongs to one Property)
àEx: 3
Property and User Reviews (One Property will have many reviews)
àEx: 4
Service Request and Call Logs
SERVICE_REQUEST
|
CALL_LOG
|
||
PK
|
SERVICE_REQUEST_NO
|
PK
|
CALL_LOG_ID
|
DESCRIPTION
|
DESCRIPTION
|
||
SERVICE_REQUEST_DT
|
CALL_LOG_DT
|
||
TYPE
|
FK
|
SERVICE_REQUEST_CALL_LOG_NO
|
|
STATUS
|
class ServiceRequest {
int serviceRequestNo;
String description;
Date serviceRequestDate;
String type;
String status;
Set<Calllog>callLogs;
}
class CallLog {
int callLogId;
String description;
Date callLogDate;
}
Ex: Property and Approval
PROPERTY
|
APPROVALS
|
||
PK
|
PROPERTY_ID
|
PK
|
APPROVAL_ID
|
DESCR
|
APPROVED_CERTIFICATE_NM
|
||
TYPE
|
DATE_OF_APPROVAL
|
||
LOCATION
|
FK
|
APPROVED_PROPERTY_ID
|
|
PRICE
|
class Approval {
int approvalId
String
approvedCertificatename;
String approvedDate;
}
class Property {
int propertyId;
String description;
String type;
String location;
float price;
Set<Approval>
approvals;
}
àImportance of
cascade and inverse:
àCascade will talks about
along with parent it’s also need to be persist. That means if we save parent
then its associated child also will be persisted. So cascade is frequently
useful in the association mappings.
àInverse talks about
always the relation is exist in other side so no need to search the relation in
itself see the relation in other side.
#1:
approval = new Approval();
approval.setApprovedCertificatename("GHMC Certificate");
approval.setApprovedDate(new Date());
property = new Property();
property.setDescription("3KBH Apartment");
property.setLocation("Ameerpate");
property.setType("Flat");
property.setPrice(121222f);
Set<Approval> approvals = new HashSet<Approval>();
approvals.add(approval);
property.setApprovals(approvals);
// session.save(approval);
session.save(property);
Foreign column=Nullable
Cascade=none (default)
Inverse=false (default)
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
àAs cascade is none, it
will not persist child obj's as it uses childs to update relationship, so
yields to Exception stating that child cannot be transient.
àNote that here we didn’t
saved the approval (commented) hence it will throws exception as
org.hibernate.TransientObjectException: object references an unsaved transient
instance - save the transient instance before flushing:
com.otm.entities.Approval.
àThat means we need to
save the approval before going to save the property.
#2:
Foreign column=Nullable
Cascade=none (default)
Inverse=false (default)
save(approval);
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
Hibernate: insert into APPROVAL (APPROVED_CERTIFICATE_NM,
DATE_OF_APPROVAL, APPROVAL_ID) values (?, ?, ?)
à[Here it will insert foriegn
column APRVD_PROPERTY_ID as NULL]
Hibernate: insert into PROPERTY (DESCR, TYPE, LOCATION, PRICE,
PROPERTY_ID) values (?, ?, ?, ?, ?)
Hibernate: update APPROVAL set APRVD_PROPERTY_ID=? where
APPROVAL_ID=?
à[Approval foriegn column
will be updated with value based on the association obj's in Set]
#3:
Foreign column=not-null
Cascade=none (default)
Inverse=false (default)
save(approval);
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
org.hibernate.PropertyValueException: not-null property references a
null or transient value.
#4:
Foreign column=Nullable
Cascade=all
Inverse=false (default)
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
Hibernate: insert into PROPERTY (DESCR, TYPE, LOCATION, PRICE,
PROPERTY_ID) values (?, ?, ?, ?, ?)
Hibernate: insert into APPROVAL (APPROVED_CERTIFICATE_NM,
DATE_OF_APPROVAL, APPROVAL_ID) values (?, ?, ?)
à[Foriegn key column is still
NULL, never Approval has been associated with property]
Hibernate: update APPROVAL set APRVD_PROPERTY_ID=? where
APPROVAL_ID=?
à[Approval foriegn column
will be updated with value based on the association obj's in Set]
#5:
Foreign column=not-null
Cascade=all
Inverse=false (default)
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
Hibernate: insert into PROPERTY (DESCR, TYPE, LOCATION, PRICE,
PROPERTY_ID) values (?, ?, ?, ?, ?)
Hibernate: insert into APPROVAL (APPROVED_CERTIFICATE_NM,
DATE_OF_APPROVAL, APRVD_PROPERTY_ID, APPROVAL_ID) values (?, ?, ?, ?)
à[It will persist even
Foriegn key column value as it is marked as not-null, it derives the foriegn
key column value based on the obj in Set]
Hibernate: update APPROVAL set APRVD_PROPERTY_ID=? where
APPROVAL_ID=?
à[Approval will be updated
with foriegn column value based on association obj in Set here this update is
not-required bcz foriegn column is already persisted but still hibernate
updates un-necessatily]
#6:
Foreign column=Nullable
Cascade=all
Inverse=true
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
Hibernate: insert into PROPERTY (DESCR, TYPE, LOCATION, PRICE,
PROPERTY_ID) values (?, ?, ?, ?, ?)
Hibernate: insert into APPROVAL (APPROVED_CERTIFICATE_NM,
DATE_OF_APPROVAL, APPROVAL_ID) values (?, ?, ?)
As foriegn key is nullable still it is NULL as approval is not
associated with property bcz now it will not looks for the relation in parent
class mapping(Property.hbm.xml) rather it looks with itself bcz
inverse="true" (child itself
Approval.hbm.xml) but no relation in it so it will inserts as NULL
PROPERTY
PROPERTY_ID
|
DSCR
|
TYPE
|
LOCARION
|
PRICE
|
1
|
3KBH Apartment
|
Flat
|
Ameerpate
|
121222
|
APPROVAL (Observe carefully)
PROPERTY_ID
|
APPROVED_CERTIFICARE_NM
|
DATE_OF_APPROVAL
|
APPROVED_PROPERTY_ID
|
1
|
GHMC Certificate
|
09-12-2015
|
NULL
|
#7:
Foreign column=NOT-NULL
Cascade=all
Inverse=true
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
ORA-01400: cannot insert NULL into ("HIB_USER"."APPROVAL"."APRVD_PROPERTY_ID")
àHere
inverse="true" that means it looks relation in itself but no relation
exist within it so it will tries to insert NULL but nt-null="true" so
it throws an Exception.
Note:
àThat means
inverse can be used for Bidirectional Relationship only.
àMany-To-One:
public class Property {
private int propertyId;
private String description;
private String type;
private String location;
private float price;
}
public class Approval {
private int approvalId;
private String
approvedCertificatename;
private Date approvedDate;
private Property property;
}
Property.hbm.xml
<hibernate-mapping package="com.otm.entities">
<class
name="Property" table="PROPERTY">
<id
name="propertyId" column="PROPERTY_ID">
<generator
class="increment" />
</id>
----
</hibernate-mapping>
Approval.hbm.xml
<hibernate-mapping package="com.otm.entities">
<class
name="Approval" table="APPROVAL">
<id
name="approvalId" column="APPROVAL_ID">
<generator
class="increment" />
</id>
<property name= "approvedCertificatename"
column="APPROVED_CERTIFICATE_NM" />
<property
name="approvedDate" column="DATE_OF_APPROVAL" />
<many-to-one name="property"
class="Property"
column="APRVD_PROPERTY_ID"
not-null="false"
cascade="all"/>
</class>
</hibernate-mapping>
àOne-To-Many/Many-To-One
(Bidirectional):
Foreign column=not-null
Cascade=all
Inverse=true
Approval [transient that means we didn’t saved approval]
Property -Set[Approvals]
property.setApprovals(approvals);
save(property);
Result:
Hibernate: insert into PROPERTY (DESCR, TYPE, LOCATION, PRICE,
PROPERTY_ID) values (?, ?, ?, ?, ?)
Hibernate: insert into APPROVAL (APPROVED_CERTIFICATE_NM,
DATE_OF_APPROVAL, APRVD_PROPERTY_ID, APPROVAL_ID) values (?, ?, ?, ?)
àAs approval is associated
with property based on which foreign column will be derived.
àOne-To-many
Using List:
àSet will not allow
duplicates and it is not in order.
àList will allows
duplicates and preserve the order of insertion based on the index of the list.
àIf at all we want
insertion order is mandatory then we can use List otherwise we can use Set.
class Property {
int propertyId;
String description;
String type;
String location;
float price;
List<Bill> bills;
}
class Bill {
int billNo;
Date billDate;
String remarks;
float amount;
}
àHere Property will have
multiple Bills so if we use list it will tracks the insertion order based on
the additional coulmn, so to preserve the order of insertion hibernate need an additional
column and hibernate will persist the values in list index column in an
sequence order and for every Property obj this index sequence column value will
reset from starting that means sequence number is specific to parent level
(Property level) but not at the table level.
àHere sequence list index
column values will be maintained by hibernate.
àImportance of
equals() and hashCode() methods in Hibernate:
àIt is not mandatory to
override equals() and hashCode() in an entity class, but it is highly recommended
to override equals() and hashCode() methods while working with collections in
hibernate.
àWhy it is
recommended:
àBasically there are two reasons
1. While working with association in order to ensure associated obj's
are properly persisted or not we need to override equlas() and hashCode()
methods.
2. While we are accessing the data from DB using hibernate to
maintain or to preserve the obj equality and DB equality per session or across
the sessions we need to override the equals() and hashCode() methods.
Note:
àThe object equality can
be derived based on the equlas() and hashCode() methods in java and Relational DB
equality can be derived based on the PK column.
Note:
àJVM will calculates the
hashCode uniquely using the prime number multiplied by considering the business
attributes hashCode will gives unique hashCode for a obj.
àWhile overriding the
equals() and hashCode() make sure that we cannot override the equals() and
hashCode() for associated objects.
àWhy we ignore
override the equals() and hashCode() for associated objs ?
Obj equality is computed based on the attributes of the actual class
but not on the basis of associated obj. If we overridden also there is no
effect it cannot be considered bcz if we overridden associated for obj then it
is also calls actual class attributes of equals() and hashCode() methods only
if in actual class hashCode() is not there then it will class super class
(Object class) which is no use so there should be an overridden methods in
actual classes. So if already equlas() and hashCode() is there why we need to
call 2-times for checking there is no need (actual class attributes are enough
to check) hence we cannot override for associated obj’s if overridden also no problem.
àwhy we should
not override equals() and hashCode() by considering only id attribute in an
entity class and why it is mandatory to override at least one of business
non-id attribute along with id attribute if at all we are overriding ?
Note that if using Set and we already overridden the equals() and
hashCode() method by considering only id attributes in a class then Hibernate
will not persist both obj bcz until it has been persisted the id=0 (transient
state) in java code for both the approvals obj's and we overridden using only
id hence it computes the hashCode by considering id property only which same
for both the obj's even though persisted data is differ (bcz it will not
consider remaining attribute while computing the hashCode for obj it only considers
id bcz we overridden for only id property hence it consider only id) so the
hashCode is same for both the obj's and we using set hence it removes one of
the duplicated obj.
So it is mandatory to consider at least one of non-id (or we can
consider any attributes as per our business data to determine equality) different
business data attribute for computing the hashCode if at all we are overriding
to identify obj uniquely and we no need to override equals and hashCodes for id
attribute bcz id attribute is in transient state in an entity class till it
gets persisted. So we prefer only non-id attributes of an entity class to
preserve the obj uniqueness.
àSet:
approvals.add(approval1);
approvals.add(approval2);
property.setApprovals(approvals);
//Version-1
session.save(property);
Note that if using Set and we already overridden the equals() and
hashCode() then Hibernate will persist only obj and discords the 2nd approval
obj bcz both are having same data so set will reomoves duplicates.
//Version-2
session.save(property);
Note that if using Set and we didn't overridden the equals() and
hashCode() then Hibernate will persist approval1 obj and approval2 obj also even though both obj's data
is same bcz by default hashCode for obj's is differ even though data is same so
Set will not be able to identify those are duplicated data bcz both obj's are
having different hashCode.
àList:
à Note that if
using List and either we already overridden or not the equals() and hashCode()
methods Hibernate will persist both the bill obj's bcz List will allows
duplicates even though both are having same data.
Note:
Similarly for all the collection we experiment.
à#1
Property property=session1.get(Property.class,1);
Property property=session1.get(Property.class,1);
àIf we overridden or not overridden
(equals(), hashCode()) hibernate default fetches from the DB only once bcz
session level cache is designed based on the obj equality of DB and java obj by
overriding in the session cache class hence again it will not goes to DB per
session based.
à1-select query only
à#2:
Property property=session1.get(Property.class,1);
Property property=session2.get(Property.class,1);
àIf we overridden or not
hibernate default fetches the data from the DB for session1 and session level
cache is designed based on the obj equality of DB and java obj by overriding in
the session cache class by the hibernate itself internally hence again it will
not goes to DB per session1 based but for session2 again it goes to DB bcz
hibernate 1st level is a session based cache it cannot see other session data
so even though for 2-sessions we fetch the data also the obj equality is same
if we overridden the equals and hashCode methods and if didn’t overridden then
for both obj’s hashCode will be differ.
à2-select queries
àOne-To-Many
Using Map:
àIn order to work with Map
we need key to store so we need one extra column to preserve the key while accessing
the corresponding data from the Map.
class Property {
int propertyId;
String description;
String type;
String location;
float price;
Map<String, Visitor> visitors;
}
class Visitor {
int vistorId;
String visitedDate;
String firstName;
String lastName;
String mobile;
String place;
String purpose;
}
PROPERTY
|
VISITORS
|
|||||||||||
PK
|
PROPERTY_ID
|
PK
|
VISITOR_ID
|
|||||||||
DESCR
|
VISITED_DT
|
|||||||||||
TYPE
|
FIRST_NM
|
|||||||||||
LOCATION
|
LAST_NM
|
|||||||||||
PRICE
|
MOBILE
|
|||||||||||
PLACE
|
||||||||||||
PURPOSE
|
||||||||||||
FK
|
PROPERTY_VISITOR_ID
|
|
|
|
|
|||||||
PROPERTY_VISITOR_SEQ_NO
|
|
|||||||||||
[Extra column PROPERTY_VISITOR_ID
to save visitor obj in to Map
Or we can use any of the column in
the
VISITORS table if any column is
unique]
|
||||||||||||
àOne-To-Many
Using Bag (Bag is a Collection type in Hibernate):
2. Component Mapping Model (Composition):
àIt is also one form of
association where one obj is containing another obj and these are having
directional relationship where one will acts as owner another will acts owney.
If the owner has been die then its owny will also will dies, if owney will dies
then there is no impact on the owner that means life time of the owney will
depends life time of the owner.
class Employee {
private int employeeId;
private String
firstName;
private String lastName;
private Date dob;
private String gender;
private String designation;
private Address address;
//settres & getters
}
class Address {
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private int zip;
private String country;
//settres & getters
}
àAddress will not have an
Employee and Employee will have an Address that means Employee owns the Address
so there is an directional relationship between the Employee and Address hence
it is called as Composition Relation. That means owney will not have an independent
existence it always depends on the owner, so that it will not have an identity.
àDifferences
between the Association Mapping and Component Mapping:
à If the relation between the 2-obj's is association there will be an
separate identity that means they can be persistable independently but if is a
composition then will be an owner and owney where owney will not have an
identity so that it cannot persistable independently. So how can we persist
this type of obj's in the relational DB model it is called as granularity mis-match.
To avoid this problem ORM-technology come uo with a concept of component mapping
which is adapted by by the hibernate ORM-technology.
EMPLOYEE
|
EMPLOYEE_ID
|
FIRST_NM
|
LAST_NM
|
DOB
|
DESIGNATION
|
GENDER
|
ADDRESS_LINE_1
|
ADDRESS_LINE_1
|
CITY
|
STATE
|
ZIP
|
COUNTRY
|
àThat means the Employee
obj and Department obj both will be persisted in a single table bcz Address cannot
be persistable independently bcz it doesn't have an identity and it always
dependent on the owner.
àEven though these obj's
are persisted on single table we cannot declare these Address attributes in
Employee class bcz Address class will not only used by the Employee there could
be some other classes which can refer the Address class attributes for this
reason we should not declare all the attributes of Employee and Address in a
single Employee class, otherwise we need to repeatedly declare the same
attributes in Employee class and Department class as well which leads to
duplication of the attributes in various classes. That means we need to declare
Address as separate table for the sake of re-usability.
class Department {
private int departmenttId;
private String
departmentName;
private Address address;
//settres & getters
}
àAs Address is non-persistable
class independently so we need to write only one mapping file.
à The Address is class/component that is exist/declared as part of
another class so we need to <component> tag in the Employee.hbm.xml
Comments
Post a Comment