Advanced Mapping Persistente Domänenmodelle mit JPA 2.0 und Bean Validation
Advanced Mapping
Persistente Domänenmodelle mit JPA 2.0 und Bean Validation
Embedded Objects
-id : int-name : String-salary : long
Employee
-id : int-street : String-city : String-state : String-zip : String
Address
0..1
2
Komposition: Mutterobjekt mit eingebetteten Objekten
Eingebettete Objekte haben keine eigene Identität
Mutterobjekt und eingebettete sind in derselben Tabelle abgelegt
EMPLOYEE
PK ID
NAME SALARY STREET CITY STATE ZIP
Embedded Objects, Beispiel
3
@Embeddablepublic class Address { private String street; private String city; private String state; private String zip;}
@Entitypublic class Employee { @Id private int id; private String name; private long salary; @Embedded private Address address;}
Enhanced Embeddables (JPA 2.0)
Verschachtelung von Embeddables und Embeddables mit Beziehungen
4
@Embeddablepublic class Assembly { ... @Embedded ShippingDetail shipDetails;
@ManyToOne Supplier supplier; ...}
5
Zusammengesetzte Primärschlüssel
public class EmployeeId implements Serializable { protected String country; protected int id;}
// Variante 1@IdClass( EmployeeId.class )@Entity public class Employee { @Id protected String country; @Id protected int id;}
// Variante 2@Entity public class Employee { @EmbeddedId public EmployeeId id;}
Composite Primary Key With Relationships (JPA 2.0)
6
@Entity @IdClass(PartPK.class)public class Part { @Id int partNo; @Id @ManyToOne Supplier supplier;}
public class PartPK { int partNo; int supplier;}
7
Read-Only Mappings und Optional
Read-Only@Column(insertable = false, updateable = false)
Optional@ManyToOne(optional = true) // Default
8
Mehrere Tabellen pro Entity
Gelegentlich wird eine Entity in der Datenbank in mehrere Tabellen modelliert oder muss umgekehrt aus mehreren Tabellen zusammengesetzt werden.
Eine Entity kann beliebig viele Sekundärtabellen haben:
@Entity@Table( name = "Employee" )@SecondaryTable( name = "EmployeeExt", pkJoinColumns = { @PrimaryKeyJoinColumn(name="idRef", referencedColumnName = "id")})public class Employee { ...}
9
Mapping von SQL-Views
Komplexe Abfragen werden in einer Datenbank gerne als (materialisierte) View vorgehalten. Um Performance-Vorteile zu nutzen, kann eine View wie eine Entity angesprochen werden. Beispiel:
@Entity public class EmployeeStats{ @Id protected long id; @Column( insertable=false, updatable=false) protected int numPhones; // ... CREATE VIEW employeestats ( id, numPhones ) AS SELECT e.id, COUNT(p.*) FROM employee e LEFT OUTER JOIN PHONES P on (…) group by e.id
10
Vererbung
Vererbungshierarchien können problemlos verwendet und abgebildet werden.
Klassen können abstrakt oder konkret sein.
Alle Klassen in der Vererbungshierarchie müssen den Primärschlüssel der Basisklasse verwenden (erben).
Es gibt vier Mappingstrategien auf die Datenbank:
Eine einzige Tabelle für die gesamte Verbungshierarchie Eine Tabelle für jede konkrete Klasse Eine Tabelle für jede Klasse Mapped Superclass
11
SINGLE_TABLE
-id : int-name : String
Project
DesignProject QualityProject
PROJECT
ID
DTYPE (O) NAME (O)
@Entity @Inheritance public class Project
@Entity public class DesignProject extends Project
@Entity public class QualityProject extends Project
12
JOINED
PROJECT
ID
DTYPE (O) NAME (O)
QUALITYPROJECT
ID (FK)DESIGNPROJECT
ID (FK)
-id : int-name : String
Project
DesignProject QualityProject
@Entity @Inheritance(strategy=InheritanceType.JOINED)public class Project
@Entity public class DesignProject extends Project
@Entity public class QualityProject extends Project
13
TABLE_PER_CLASS (Optional)
-id : int-name : String
Project
DesignProject QualityProject
DesignProject
name (O)
QualityProject
name (O)
@Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)public class Project
@Entity public class DesignProject extends Project
@Entity public class QualityProject extends Project
14
MAPPED_SUPERCLASS
-phonenumber : String-type : String
Phone
-id : Integer-createdAt : Date-createdFrom : String-updatedAt : String-updatedFrom : String-version : Integer
BaseEntity// Klasse BaseEntity@MappedSuperclasspublic abstract class BaseEntity { @Id @GeneratedValue protected Integer id; protected Integer version; protected Timestamp createdAt; protected String createdFrom; protected Timestamp updatedAt; protected String updatedFrom;
// Klasse Phone@Entitypublic class Phone extends BaseEntity