Kann mir das bitte jemand erklären @MapsId
im Winterschlaf? Es fällt mir schwer, es zu verstehen.
Es wäre toll, wenn man es an einem Beispiel erklären könnte und in welchen Anwendungsfällen ist es am besten anwendbar?
kopflastig
Kann mir das bitte jemand erklären @MapsId
im Winterschlaf? Es fällt mir schwer, es zu verstehen.
Es wäre toll, wenn man es an einem Beispiel erklären könnte und in welchen Anwendungsfällen ist es am besten anwendbar?
Hier ist eine schöne Erklärung von Objekt-DB.
Bezeichnet ein ManyToOne- oder OneToOne-Beziehungsattribut, das die Zuordnung für einen EmbeddedId-Primärschlüssel, ein Attribut innerhalb eines EmbeddedId-Primärschlüssels oder einen einfachen Primärschlüssel der übergeordneten Entität bereitstellt. Das value-Element gibt das Attribut innerhalb eines zusammengesetzten Schlüssels an, dem das Beziehungsattribut entspricht. Wenn der Primärschlüssel der Entität denselben Java-Typ hat wie der Primärschlüssel der Entität, auf die durch die Beziehung verwiesen wird, wird das Wertattribut nicht angegeben.
// parent entity has simple primary key
@Entity
public class Employee {
@Id long empId;
String name;
...
}
// dependent entity uses EmbeddedId for composite key
@Embeddable
public class DependentId {
String name;
long empid; // corresponds to primary key type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MapsId("empid") // maps the empid attribute of embedded id
@ManyToOne Employee emp;
}
Lies das API-Dokumente Hier.
Aber was ist daran so schön? Auch ohne @MapsId kann man JoinColumn mit dem gleichen Effekt verwenden, oder nicht? Und wenn ja, sagt dieses Beispiel nicht wirklich, wofür diese Anmerkung wirklich gut ist.
– Maksim Gumerov
23. März ’18 um 14:06
Da beide Entitäten denselben Primärschlüssel verwenden, ist die Entität mit einer Spalte gekennzeichnet durch @MapsId
wird in der Persistenzschicht (Datenbank) nur die Primärschlüsselspalte haben. Die Idee ist, den Primärschlüssel zwischen den beiden Entitäten zu teilen.
– johanwannheden
7. Juni ’18 um 5:32
Was ist ein EmbeddedId-Primärschlüssel? Wie unterscheidet es sich vom normalen Primärschlüssel?
– sofs1
9. Juni ’18 um 20:40 Uhr
“Das Wertelement gibt das Attribut innerhalb eines zusammengesetzten Schlüssels an, dem das Beziehungsattribut entspricht. ” 1) Was ist mit Wertelement gemeint, geben Sie bitte ein Beispiel an? 2) Was ist ein zusammengesetzter Schlüssel? 3) Was ist das Beziehungsattribut und geben Sie ein Beispiel?
– sofs1
9. Juni ’18 um 21:09
@MaksimGumerov es ist effizient, weil man es holen kann Dependent
nur durch die Kenntnis der Kennung von Employee
.
– Emmanuel Osimosu
28. Juni ’18 um 19:30
Tonsic
Ich fand diesen Hinweis auch nützlich: @MapsId
im Ruhezustand ordnet die Annotation eine Spalte der Spalte einer anderen Tabelle zu.
Es kann auch verwendet werden, um denselben Primärschlüssel zwischen 2 Tabellen zu teilen.
Beispiel:
@Entity
@Table(name = "TRANSACTION_CANCEL")
public class CancelledTransaction {
@Id
private Long id; // the value in this pk will be the same as the
// transaction line from transaction table to which
// this cancelled transaction is related
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_TRANSACTION", nullable = false)
@MapsId
private Transaction transaction;
....
}
@Entity
@Table(name = "TRANSACTION")
@SequenceGenerator(name = "SQ_TRAN_ID", sequenceName = "SQ_TRAN_ID")
public class Transaction {
@Id
@GeneratedValue(generator = "SQ_TRAN_ID", strategy = GenerationType.SEQUENCE)
@Column(name = "ID_TRANSACTION", nullable = false)
private Long id;
...
}
Wo füge ich @MapsId in eine bidirektionale Assoziation ein? Sollten beide Klassen haben @MapsId
. Macht es überhaupt einen Unterschied?
– marcus
2. Okt ’18 um 21:32
Ich denke, ein Tisch wird der “Eigentümer” des ursprünglichen Pk sein (der mit @Id
und @GeneratedValue
und @Column
) und habe a @OneToOne
und @JoinColumn
mit der anderen Tabelle, und die andere Tabelle hat die @MapsId
. Dies würde jedoch wahrscheinlich nicht funktionieren, wenn Sie zuerst in die ‘andere Tabelle’ EINFÜGEN möchten.
– Tonsic
19. November ’18 um 22:02
Ein schöner Artikel über diese Art der Verwendung (mit der ID aus einer anderen Tabelle als ID einer anderen Entität) ist hier vladmihalcea.com/…
– Lubo
23. Okt ’19 um 5:03
Aber wenn Sie Transaktionen aus stornierten herausfiltern möchten, ist dies eine häufige Ursache. Wie ist das effizienter? Ich meine, für SQL müssen Sie nur NOT NULL für TRANSACTION.fk_cancelled_id sagen, aber in diesem Fall werden mehr Operationen durchgeführt.
– M_F
10. Mai ’20 um 8:04
In diesem speziellen Fall hier ist es üblich, eine Spalte wie “Typ” in der Basisklasse und in der Tabelle zu verwenden, in der Sie angeben, ob die Transaktion vom Typ “Abbrechen” oder einem anderen ist.
– Tonsic
11. Mai ’20 um 16:03
Jaumzera
IMHO, der beste Weg, darüber nachzudenken @MapsId
ist, wenn Sie einen zusammengesetzten Schlüssel in einer an:m-Entität zuordnen müssen.
Ein Kunde kann beispielsweise einen oder mehrere Berater haben und ein Berater kann einen oder mehrere Kunden haben:
Und Ihre Entites wären ungefähr so (Pseudo-Java-Code):
@Entity
public class Customer {
@Id
private Integer id;
private String name;
}
@Entity
public class Consultant {
@Id
private Integer id;
private String name;
@OneToMany
private List<CustomerByConsultant> customerByConsultants = new ArrayList<>();
public void add(CustomerByConsultant cbc) {
cbc.setConsultant(this);
this.customerByConsultant.add(cbc);
}
}
@Embeddable
public class ConsultantByConsultantPk implements Serializable {
private Integer customerId;
private Integer consultantId;
}
@Entity
public class ConsultantByConsultant {
@EmbeddedId
private ConsultantByConsultantPk id = new ConsultantByConsultantPk();
@MapsId("customerId")
@JoinColumn(insertable = false, updatable = false)
private Customer customer;
@MapsId("consultantId")
@JoinColumn(insertable = false, updatable = false)
private Consultant consultant;
}
Auf diese Weise zuordnen, fügt JPA automatisch ein Customer
und Consultant
IDs in der EmbeddableId
wann immer Sie einen Berater speichern. Sie müssen die also nicht manuell erstellen ConsultantByConsultantPk
.
Wie er Vladimir in seinem . erklärte Lernprogramm, Die beste Methode zum Zuordnen einer @OneToOne-Beziehung ist die Verwendung von @MapsId. Auf diese Weise benötigen Sie nicht einmal eine bidirektionale Zuordnung, da Sie die Child-Entität immer mithilfe der Parent-Entity-ID abrufen können.
Mit MapsId können Sie denselben Primärschlüssel zwischen zwei verschiedenen Entitäten/Tabellen verwenden. Hinweis: Wenn Sie MapsId verwenden, wird die CASCADE.ALL
Flag wird nutzlos, und Sie müssen sicherstellen, dass Ihre Entitäten manuell gespeichert werden.
.