Kann mir bitte jemand @MapsId
im Winterschlaf erklären ? Es fällt mir schwer, das zu verstehen.
Es wäre großartig, wenn man es anhand eines Beispiels erklären könnte und in welchen Anwendungsfällen ist es am besten anwendbar?
Kann mir bitte jemand @MapsId
im Winterschlaf erklären ? Es fällt mir schwer, das zu verstehen.
Es wäre großartig, wenn man es anhand eines Beispiels erklären könnte und in welchen Anwendungsfällen ist es am besten anwendbar?
Antworten:
Hier ist eine schöne Erklärung von Object 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 in einem zusammengesetzten Schlüssel an, dem das Beziehungsattribut entspricht. Wenn der Primärschlüssel der Entität vom selben Java-Typ ist wie der Primärschlüssel der Entität, auf die in der 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;
}
Lesen Sie hier die API-Dokumente .
@MapsId
will in der Persistenzschicht (Datenbank) bezeichneten Spalte nur eine Primärschlüsselspalte. Die Idee ist, den Primärschlüssel zwischen den beiden Entitäten zu teilen.
Dependent
nur durch Kenntnis der Kennung von abrufen können Employee
.
Ich fand diesen Hinweis auch nützlich: @MapsId
Im Ruhezustand ordnet Annotation eine Spalte der Spalte einer anderen Tabelle zu.
Es kann auch verwendet werden, um denselben Primärschlüssel zwischen zwei 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;
...
}
@MapsId
. Macht es überhaupt einen Unterschied?
@Id
und @GeneratedValue
und @Column
) und ein @OneToOne
und @JoinColumn
mit der anderen Tabelle haben, und die andere Tabelle wird die haben @MapsId
. Dies würde jedoch wahrscheinlich nicht funktionieren, wenn Sie zuerst in die 'andere Tabelle' EINFÜGEN möchten.
Wie er Vladimir in seinem Tutorial erklärte , ist die Verwendung von @MapsId der beste Weg, eine @ OneToOne-Beziehung abzubilden. Auf diese Weise benötigen Sie nicht einmal eine bidirektionale Zuordnung, da Sie die untergeordnete Entität jederzeit mithilfe der übergeordneten Entitätskennung 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 das CASCADE.ALL
Flag unbrauchbar und Sie müssen sicherstellen, dass Ihre Entitäten manuell gespeichert werden.
IMHO, der beste Weg, um darüber nachzudenken @MapsId
wenn Sie einen zusammengesetzten Schlüssel in einer: m-Entität zuordnen müssen.
Zum Beispiel kann ein Kunde einen oder mehrere Berater haben und ein Berater kann einen oder mehrere Kunden haben:
Und Ihre Entitäten 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)
Customer customer;
@MapsId("consultantId")
@JoinColumn(insertable = false, updatable = false)
Consultant consultant;
}
Auf diese Weise fügt JPA automatisch Customer
und Consultant
IDs ein, EmbeddableId
wenn Sie einen Berater speichern. Sie müssen das also nicht manuell erstellen ConsultantByConsultantPk
.