Entity Relationships
Seven Relationship Types
• Four types of cardinality:– One-to-One– One-to-Many– Many-to-One– Many-to-Many
• Each relationship can be:– Unidirectional– Bidirectional
• One-to-Many and Many-to-One bidirectional relationships are identical
Relationships
• In order to model real-world business concepts, entity beans must be capable of forming complex relationships– Examples:
•A Customer entity can have a one-to-one relationship with an Address entity
•A Customer entity can have a one-to-many relationship with a Phone entity
• Represent the navigability of the domain model
• Specified by applying annotations to related entity beans
One-to-One UnidirectionalRelationship
One-to-One Unidirectional Relationship
Customer+ getLastName() : String+ setLastName(In : String) : void
+ getFirstName() : String+ setFirstName(In : String) : void
+ getAddress() : Address+ setAddress(In : Address) : void
Address+ getStreet() : String+ setStreet(In : String) : void
+ getCity() : String+ setCity(In : String) : void
…
11
One-to-One Unidirectional – Relational Database Schema
• CUSTOMER table contains a foreign key to the ADDRESS table
• ADDRESS table does not contain a foreign key to the CUSTOMER table
One-to-One Unidirectional – Entity Annotation
@Entitypublic class Customer implements java.io.Serializable {...private Address address;...@OneToOne(cascade={CascadeType.ALL})@JoinColumn(name=“ADDRESS_ID”)public Address getAddress() {
return address;}public void setAddress(Address addr) {
this.address = addr;}
One-to-One BidirectionalRelationship
One-to-One Bidirectional Relationship
Customer+ getLastName() : String+ setLastName(In : String) : void
+ getFirstName() : String+ setFirstName(In : String) : void
+ getCreditCard() : CreditCard+ setCreditCard(In : CreditCard) : void
CreditCard+ getNumber() : String+ setNumber(In : String) : void
+ getExpiration() : Date+ setExpiration(In : Date) : void
+ getCustomer() : Customer+ setCustomer(In : Customer) : void
11
One-to-One Bidirectional – Relational Database Schema
• CUSTOMER table contains a foreign key to the CREDIT_CARD table
• CREDIT_CARD table does not contain a foreign key to the CUSTOMER table
• Bidirectional relationship established and maintained by the application programmer, not the persistence provider
One-to-One Bidirectional – Entity Annotation
@Entitypublic class Customer implements java.io.Serializable {...private CreditCard credCard;...@OneToOne(cascade={CascadeType.ALL})@JoinColumn(name=“CREDIT_CARD_ID”)public CreditCard getCreditCard() {
return credCard;}public void setCreditCard(CreditCard cc) {
this.credCard = cc;}
One-to-One Bidirectional – Entity Annotation
@Entitypublic class CreditCard implements java.io.Serializable {...private Customer customer;...@OneToOne(mappedBy=“creditCard”)public Customer getCustomer() {
return customer;}public void setCustomer(Customer cust) {
this.customer = cust;}
One-to-One Bidirectional – Establishing the Relationship
Customer cust = new Customer();CreditCard card = new CreditCard();cust.setCreditCard(card);card.setCustomer(cust);
One-to-One Bidirectional – Modifying the Relationship
Customer newCust = em.find(Customer.class, newCustId);
CreditCard card = oldCustomer.getCreditCard();
oldCustomer.setCreditCard(null);newCust.setCreditCard(card);card.setCustomer(newCust);
One-to-Many UnidirectionalRelationship
One-to-Many Unidirectional Relationship
Customer+ getLastName() : String+ setLastName(In : String) : void
+ getFirstName() : String+ setFirstName(In : String) : void
+ getPhones() : Collection<Phone>+ setPhones(In : Collection<Phone>)
: void
Phone+ getNumber() : String+ setNumber(In : String) : void
+ getType() : String+ setType(In : String) : void
*1
One-to-Many Unidirectional – Relational Database Schema
• Could be mapped with a join table or:
• PHONE table contains a foreign key to the CUSTOMER table (reverse pointer scenario)
One-to-Many Unidirectional – Entity Annotation@Entitypublic class Customer implements java.io.Serializable {...private Collection<Phone> phones =
new ArrayList<Phone>();...@OneToMany(cascade={CascadeType.ALL})@JoinColumn(name=“CUSTOMER_ID”)public Collection<Phone> getPhones() {
return phones;}public void setPhones(Collection<Phone> p) {
this.phones = p;}
One-to-Many Unidirectional – Establishing the Relationship
Customer cust = em.find(Customer.class, pk);Phone ph = new Phone(“617-333-3333”, 5);cust.getPhones().add(ph);
One-to-Many Unidirectional – Removing the Relationship
cust.getPhones().remove(ph);em.remove(ph);
One-to-Many Unidirectional – Join Table Mapping@Entitypublic class Customer implements java.io.Serializable {
...private Collection<Phone> phones =
new ArrayList<Phone>();...@OneToMany(cascade={CascadeType.ALL})@JoinTable(name=“CUSTOMER_PHONE”,
joinColumns={@JoinColumn(name=“CUSTOMER_ID”)}, inverseJoinColumns={@JoinColumn(name=“PHONE_ID”)})
public Collection<Phone> getPhones() {return phones;
}public void setPhones(Collection<Phone> p) {
this.phones = p;}
Many-to-One UnidirectionalRelationship
Many-to-One Unidirectional Relationship
Flight+ getNumber() : int+ setNumber(In : int) : void
+ getPlane() : Plane+ setPlane(In : Plane) : void
Plane+ getModel() : String+ setModel(In : String) : void
…1*
Many-to-One Unidirectional – Relational Database Schema
• FLIGHT table contains a foreign key to the PLANE table
Many-to-One Unidirectional – Entity Annotation
@Entitypublic class Flight implements java.io.Serializable {...private Plane plane;...@ManyToOne@JoinColumn(name=“PLANE_ID”)public Plane getPlane() {
return plane;}public void setPlane(Plane pl) {
this.plane = pl;}
One-to-Many BidirectionalRelationship
One-to-Many Bidirectional Relationship
Reservation+ getNumber() : int+ setNumber(In : int) : void
+ getRes() : Collection<Reservation>+ setRes(In : Collection<Reservation>)
: void
Flight
+ getDate() : Date+ setDate(In : Date) : void
+ getFlight() : Flight+ setFlight(In : Flight) : void
…
1*
One-to-Many Bidirectional – Relational Database Schema
• RESERVATION table contains a foreign key to the FLIGHT table
One-to-Many Bidirectional – Entity Annotation
@Entitypublic class Reservation implements java.io.Serializable {...private Flight flight;...@ManyToOne@JoinColumn(name=“FLIGHT_ID”)public Flight getFlight() {
return flight;}public void setFlight(Flight fl) {
this.flight = fl;}
One-to-Many Bidirectional – Entity Annotation@Entitypublic class Flight implements java.io.Serializable {...private Collection<Reservation> res =
new ArrayList<Reservation>();...@OneToMany(mappedBy=“flight”)public Collection<Reservation> getRes() {
return res;}public void setRes(Collection<Reservation> r) {
this.res = r;}
Many-to-Many BidirectionalRelationship
Many-to-Many Bidirectional Relationship
Reservation+ getName() : String+ setName(In : String) : void
+ getRes() : Collection<Reservation>+ setRes(In : Collection<Reservation>)
: void
Customer
+ getDate() : Date+ setDate(In : Date) : void
+ getCust() : Collection<Customer>+ setCust(In : Collection<Customer>)
: void
**
Many-to-Many Bidirectional – Relational Database Schema
• Use a RESERVATION_CUSTOMER association table
Many-to-Many Bidirectional – Entity Annotation@Entitypublic class Reservation implements
java.io.Serializable {...private Set<Customer> custs =
new HashSet<Customer>();...@ManyToMany@JoinTable(name=“RESERVATION_CUSTOMER”), joinColumns={@JoinColumn(name=“RESERVATION_ID”)},
inverseJoinColumns={@JoinColumn(name=“CUSTOMER_ID”)})public Set<Customer> getCust() {
return custs;}public void setCust(Set<Customer> cu) {
this.custs = cu;}
Many-to-Many Bidirectional – Entity Annotation@Entitypublic class Customer implements java.io.Serializable {...private Collection<Reservation> res =
new ArrayList<Reservation>();...@ManyToMany(mappedBy=“cust”)public Collection<Reservation> getRes() {
return res;}public void setRes(Collection<Reservation> r) {
this.res = r;}
Many-to-Many UnidirectionalRelationship
Many-to-Many Unidirectional Relationship
Reservation+ getLocation() : String+ setLocation(In : String) : void
PlaneSeat
+ getDate() : Date+ setDate(In : Date) : void
+ getSeats() : Collection<PlaneSeat>+ setSeats(In : Collection<PlaneSeat>)
: void
**
Many-to-Many Unidirectional – Relational Database Schema
• Use a RESERVATION_PLANESEAT association table
Many-to-Many Unidirectional – Entity Annotation@Entitypublic class Reservation implements
java.io.Serializable {...private Set<PlaneSeat> planeSeats =
new HashSet<PlaneSeat>();...@ManyToMany@JoinTable(name=“RESERVATION_PLANESEAT”), joinColumns={@JoinColumn(name=“RESERVATION_ID”)},
inverseJoinColumns={@JoinColumn(name=“PLANESEAT_ID”)})public Set<PlaneSeat> getSeats() {
return planeSeats;}public void setSeats(Set<PlaneSeats> ps) {
this.planeSeats = ps;}
Cascading
cascade
• Attribute of @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany relationship annotations
@OneToOne(cascade={CascadeType.ALL})
Cascading
• When you preform an entity manager operation on an entity, you can automatically have the same operation performed on any relationship properties the entity may have
• Example: Customer entity has one-to-one relationship with Address entity and one-to-many relationship with Phone entity
Customer cust = new Customer();cust.setAddress(new Address());cust.getPhones().add(new Phone());// create all in one entity manager invocationentityManager.persist(cust);
Applying Cascading
• Cascading can be applied to a variety of entity manager operations using javax.persistence.CascadeType:
public enum CascadeType{ALL, PERSIST, MERGE, REMOVE, REFRESH
}
Cascade Types
• PERSIST– Inserts records of related objects
• MERGE– Inserts and updates records of related
objects• REMOVE
– Removes records of related objects• REFRESH
– Refreshes related object from the database
• ALL– Combination of all of the above
When to Use Cascading
• Not always applicable– Example: Do not want to remove a
related Flight when removing a Reservation
• Cascading simply a convenience tool for reducing the number of EntityManager API calls
Seven Relationship Types
• Four types of cardinality:– One-to-One– One-to-Many– Many-to-One– Many-to-Many
• Each relationship can be:– Unidirectional– Bidirectional
• One-to-Many and Many-to-One bidirectional relationships are identical