Dies ist eine alte Version des Dokuments!
LU10b - Objekte vs. Fremdschlüssel
Grundsätzlich kann man bei den JPA-Klassen entweder den Fremdschlüssel oder direkt das Zielobjekt selbst als Feld verwenden.
| Datenbankorientiertes Modell | Objektorientiertes Modell |
|---|---|
@Entity @Getter @Setter public class Account { ... @ManyToOne @JoinColumn(name = "project_id", nullable = false) private Project project; ... } |
|
String projectName = projectRepository.findById(account.getProjectId()).getProjectName(); | String projectName = account.getProject().getProjectName(); |
Der „objektorientierte“ Ansatz ermöglicht es im Code von einer Entität eine andere aufzurufen, ohne, dass diese jedes Mal manuell geladen werden müssen.
Das erleichtert die Schreibweise als auch die Abhängigkeiten, da man im obigen Beispiel zusätzlich noch Zugriff auf projectRepository benötigt.
Besonders bei längeren Ketten von Entitäten, wird der Code bei der „datenbankorientierten“ Variante aufgrund der manuellen „findById“-Methoden schnell komplex und unübersichtlich.
Lazy Loading
Beim „objektorientierten“ Ansatz wird ein sogenanntes Lazy Loading angewendet. Das heisst, es werden nicht alle verknüpften Objekte zu Beginn miteinander geladen, sondern nur die tatsächlich benötigten Objekte nach und nach.
Account account = accountRepository.findById(accountId).get(); // Holt das Account-Objekt inklusive dem FK project_id String projectName = account.getProject().getProjectName(); // Kein nachladen nötig, weil project_name dem Fremdschlüssel entspricht String passwordHash = account.getProject().getPasswordHash(); // Hier wird im Hintergrund automatisch das Project-Objekt geladen
References
Um ein Objekt mittels einem Objekt zu suchen oder zu löschen, muss nicht das zwingend das ganze Objekte erstellt werden, sondern lediglich die Werte der Fremdschlüssel.
| Operation | Via Join | Via Reference-Object |
|---|---|---|
| find | List<Account> accounts = accountRepository.findByProject_ProjectName(projectName); | Project projectRef = entityManager.getReference(Project.class, projectName); List<Account> accounts = accountRepository.findByProject(project); |
| delete | accountRepository.deleteByAccountNumberAndProject_ProjectName(accountNumber, projectName); | Project projectRef = entityManager.getReference(Project.class, projectName); accountRepository.deleteByAccountNumberAndProject(accountNumber, projectRef); |