Introduction to Java EEJava Persistence API (JPA)
Relationships
Kinds of relationshipsUML associations and aggregations (ER non-
identifying relationships, shared semantics)One-to-oneOne-to-manyMany-to-oneMany-to-many
UML compositions (ER identifying relationships, non-shared semantics)One-to-oneOne-to-many
Java Persistence API - relationships 2
@Entitypublic class Order implements Serializable { @Id private int id; private String orderName; @OneToOne private Shipment shipment; ... public Shipment getShipment() { return shipment; } public void setShipment(Shipment shipment) { this.shipment = shipment; }}
Table Order has foreign key to table Shipment
Java Persistence API - relationships 3
Association and aggregation: unidirectional one-to-one
Java Persistence API - relationships 4
Attribute cascadeExample above could be written this way too:
@OneToOne(cascade={CascadeType.PERSIST})private Shipment shipment;
We specified that method persist() invoked on entity Order must cascade to related entity Shipment
Attribute cascade may have these values:PERSIST, MERGE, REMOVE, REFRESH, and ALL
Java Persistence API - relationships 5
Association and aggregation:bidirectional one-to-one@Entitypublic class Shipment implements Serializable { @Id private int id; private String city; private String zipcode; @OneToOne(mappedBy=”shipment”) private Order order; public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; }}
Table Order has foreign key to table Shipmentbecause Order is owner of the relationship
Java Persistence API - relationships 6
Association and aggregation: unidirectional many-to-one@Entitypublic class Employee implements Serializable { ... @ManyToOne private Company company;
public Company getCompany() { return this.company; } public void setCompany(Company company){ this.company = company; }}
Table Employee contains a foreign key to table Company.
Java Persistence API - relationships 7
Association and aggregation: bidirectional many-to-one@Entitypublic class Company implements Serializable { ... @OneToMany(mappedBy="company") private Collection<Employee> employees;
public Collection<Employee> getEmployees() { return this.employees; } public void setEmployees(Collection<Employee> employees){ this.employees = employees; }}
Java Persistence API - relationships 8
Association and aggregation: unidirectional one-to-manyPer JPA specification:
Unidirectional multi-valued relationships always have join table (!)
That is, we cannot have unidirectional one-to-many relationship with the owner being on “one” side
We can: create bidirectional relationship, owner must
be “many” sideor create join table
Java Persistence API - relationships 9
Association and aggregation: unidirectional many-to-many@Entitypublic class Student implements Serializable { @ManyToMany @JoinTable(name=”STUDENT_COURSE”) private Collection<Course> courses;
public Collection<Course> getCourses() { return courses; } public void setCourses(Collection<Course> courses) { this.courses = courses; }}
Java Persistence API - relationships 10
Association and aggregation: bidirectional many-to-many@Entitypublic class Course implements Serializable { @ManyToMany(mappedBy="courses") private Collection<Student> students;
public Collection<Student> getStudents() { return students; } public void setStudents(Collection<Students> students) { this.students = students; }}
Java Persistence API - relationships 11
Association and aggregation:what needs to be knownFor one-to-one bidirectional relationships, the
owning side corresponds to the side that contains the corresponding foreign key
The many side of one-to-many / many-to-one bidirectional relationships must be the owning sidehence the mappedBy element cannot be
specified on the ManyToOne annotation.For many-to-many bidirectional relationships
either side may be the owning side
Java Persistence API - relationships 12
Association and aggregation:what needs to be knownBidirectional relationships will be persisted based
on references held by the owning side of the relationshipIt is the developer’s responsibility to keep the in-
memory references held on the owning side and those held on the inverse side consistent with each other when they change
It is particularly important to ensure that changes to the inverse side of a relationship result in appropriate changes on the owning side, so as to ensure the changes are not lost when they are synchronized to the database
Kinds of relationships – aggregation
Room – Chairidentity of chair does not depend on identity of roomchair is sharable – we can move chair from one room to
another, and chair will not change its identitychair may exist without room – it may temporarily be
placed outside of the houseAll these properties characterize aggregation
relationship – relationship with sharable semanticsAlso known as non-identifying relationships in ER modeling
Java Persistence API - relationships 13
House Room Chair
Kinds of relationships – composition
House – Room identity of room depends on identity of house – room is always
part of some house if house would change its identity (imagine reconstruction), rooms most
probably would be renumbered room is non-sharable – we cannot move room from one house to
anotherroom cannot exist without house – if we destroy house, all its
rooms are destroyed implicitlyAll these properties characterize composition relationship –
relationship with non-sharable semanticsAlso known as identifying relationships in ER modeling
Java Persistence API - relationships 14
House Room Chair
Java Persistence API - relationships 15
Implementing composition with JPAThere are two ways to model composition (ER
identifying) relationship:Usual one-to-many relationship with
additionally applied non-shared semantics (automatic orphan deletion) – attribute orphanRemoval as noted above, programmer must take care of both
ends of relationshipSpecialized relationship – embedded element
collection (@ElementCollection) it is enough to take care of one end of relationship
Java Persistence API - relationships 16
Composition:one-to-many with orphan removalRelationships @OneToOne and @OneToMany may be
specified with orphanRemoval=true@Entitypublic class House { @OneToMany(mappedBy="room", orphanRemoval=true) Collection<Room> rooms;}This way we are requesting non-sharable semantics –
if relation “child – parent” gets broken (parent is destroyed, or child is removed from parent’s collection), child is destroyed automatically
Java Persistence API - relationships 17
Composition:one-to-many with orphan removalIn the example above:
If room gets removed from house’s collection (e.g.: house.getRooms.remove(0)), then the room will be deleted from DB automatically
If house is deleted from database then all its rooms are deleted from database automatically
Note: programmer must obey the rules of non-sharable semanticsRemoving one room from some house’s collection
and adding it to other house’s collection would violate rules of non-sharable semantics
Java Persistence API - relationships 18
Example
Java Persistence API - relationships 19
Composition: StudyJournal – Recordembedded element collectionpublic class StudyJournal implements Serializable { @ElementCollection @CollectionTable( name=“Record", joinColumns=@JoinColumn(name=“Student_id")) private List<Record> records;
...}
Java Persistence API - relationships 20
Composition: StudyJournal – Recordembedded element collection@Embeddable // not @Entity !public class Record implements Serializable { @Column(name = "semester") private String semester; @Column(name = "courseTitle") private String courseTitle; @Column(name = "assessment") private Integer assessment;
... setters/getters ...
public boolean equals(Object obj) {...} public int hashCode() {...}}
Composition: Student – StudyJournal
One-to-one relationship cannot be implemented as embedded element collection, we use orphanRemoval attribute instead:
In entity "Student":@OneToOne(mappedBy = "student", orphanRemoval=true)private StudyJournal studyJournal;
In dependent entity "StudyJournal":@Id@OneToOne@JoinColumn(name = "Student_id", referencedColumnName = "id")private Student student;Java Persistence API - relationships 21
Java Persistence API - relationships 22
What is important for an architectData/information models can be design in
different abstraction levels:Logical UML class diagrams
many kinds of relationships (association, aggregation, composition, etc.)
normal forms are not being applied usuallyLogical ER models
two relationships (identifying and not-identifying) normal forms are being applied
Physical ER models data types and other physical properties (table
partitioning etc.) are specified
Java Persistence API - relationships 23
What is important for an architectIf database is designed with wrong
relationships (aggregation in place of composition):you will not be able to use embeddable element
collectionsyou’ll have to use @OneToMany relationship
with orphan removal set to true and take care of both ends of the relationship –
more chances that programmer will make a mistakeConclusion: architect must participate in
data/information logical model reviews
Top Related