Java hat das Schlüsselwort transient
. Warum hat JPA @Transient
anstatt einfach das bereits vorhandene Schlüsselwort Java?
Javas Schlüsselwort transient
gibt an, dass ein Feld nicht serialisiert werden soll, wohingegen JPAs @Transient
Annotation wird verwendet, um anzuzeigen, dass ein Feld in der Datenbank nicht persistiert werden soll, d. h. ihre Semantik ist unterschiedlich.
Weil sie unterschiedliche Bedeutungen haben. Das @Transient
Annotation weist den JPA-Anbieter an, kein (non -transient
) Attribut beizubehalten. Der andere Befehl weist das Serialisierungsframework an, ein Attribut nicht zu serialisieren. Vielleicht möchten Sie ein @Transient
Eigenschaft und serialisieren Sie es immer noch.
Wie andere bereits gesagt haben, wird @Transient
Verwendet, um Felder zu markieren, die nicht beibehalten werden sollen. Betrachten Sie dieses kurze Beispiel:
public enum Gender { MALE, FEMALE, UNKNOWN }
@Entity
public Person {
private Gender g;
private long id;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public Gender getGender() { return g; }
public void setGender(Gender g) { this.g = g; }
@Transient
public boolean isMale() {
return Gender.MALE.equals(g);
}
@Transient
public boolean isFemale() {
return Gender.FEMALE.equals(g);
}
}
Wenn diese Klasse der JPA zugeführt wird, werden die gender
und id
beibehalten, es wird jedoch nicht versucht, die booleschen Hilfsmethoden beizubehalten - ohne @Transient
Würde das zugrunde liegende System dies beanstanden der Entitätsklasse Person
fehlen die Methoden setMale()
und setFemale()
und sie würden daher Person
überhaupt nicht beibehalten.
Zweck ist anders:
Das transient
Schlüsselwort und die @Transient
Annotation haben zwei verschiedene Zwecke: eine befasst sich mit Serialisierung und eine befasst sich mit Persistenz. Als Programmierer verbinden wir diese beiden Konzepte oft zu einem, was jedoch im Allgemeinen nicht zutreffend ist. Persistenz bezieht sich auf die Eigenschaft des Staates, die den Prozess überlebt, der ihn geschaffen hat. Serialisierung in Java bezieht sich auf den Vorgang des Codierens/Decodierens des Status eines Objekts als Byte-Stream.
Das Schlüsselwort transient
ist eine stärkere Bedingung als @Transient
:
Wenn ein Feld das Schlüsselwort transient
verwendet, wird dieses Feld nicht serialisiert, wenn das Objekt in einen Byte-Stream konvertiert wird. Da JPA außerdem Felder, die mit dem Schlüsselwort transient
markiert sind, mit der Annotation @Transient
Behandelt, wird das Feld auch von JPA nicht beibehalten.
Auf der anderen Seite werden nur mit @Transient
Annotierte Felder wird in einen Byte-Stream konvertiert, wenn das Objekt serialisiert wird, aber von JPA nicht beibehalten. Daher ist das Schlüsselwort transient
eine stärkere Bedingung als die Annotation @Transient
.
Beispiel
Dies wirft die Frage auf: Warum sollte jemand ein Feld serialisieren wollen, das nicht in der Datenbank der Anwendung gespeichert ist? Die Realität ist, dass Serialisierung nicht nur für die Persistenz verwendet wird. In einer Enterprise Java -Anwendung muss ein Mechanismus zum Austauschen von Objekten zwischen verteilten Komponenten vorhanden sein. Die Serialisierung bietet ein gemeinsames Kommunikationsprotokoll, um dies zu handhaben. Somit kann ein Feld kritische Informationen zum Zwecke der Kommunikation zwischen Komponenten enthalten; Aus Sicht der Persistenz hat dasselbe Feld jedoch möglicherweise keinen Wert.
Angenommen, ein Optimierungsalgorithmus wird auf einem Server ausgeführt, und die Ausführung dieses Algorithmus dauert mehrere Stunden. Für einen Kunden ist es wichtig, über die aktuellsten Lösungen zu verfügen. Auf diese Weise kann ein Client den Server abonnieren und während der Ausführungsphase des Algorithmus regelmäßige Aktualisierungen erhalten. Diese Updates werden mit dem Objekt ProgressReport
bereitgestellt:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
Die Klasse Solution
könnte folgendermaßen aussehen:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Der Server speichert jeden ProgressReport
in seiner Datenbank. Der Server kümmert sich nicht darum, estimatedMinutesRemaining
beizubehalten, aber der Client kümmert sich mit Sicherheit um diese Informationen. Daher wird das estimatedMinutesRemaining
mit @Transient
Kommentiert. Wenn das endgültige Solution
vom Algorithmus gefunden wird, wird es von JPA direkt ohne Verwendung eines ProgressReport
beibehalten.
Wenn Sie nur möchten, dass ein Feld nicht beibehalten wird, funktionieren sowohl transient als auch @ transient. Aber die Frage ist, warum @ Transient da transient bereits existiert.
Weil das @ Transient-Feld immer noch serialisiert wird!
Angenommen, Sie erstellen eine Entität und führen eine CPU-intensive Berechnung durch, um ein Ergebnis zu erhalten. Dieses Ergebnis wird nicht in der Datenbank gespeichert. Wenn Sie die Entität jedoch an andere Java) - Anwendungen senden möchten, die von JMS verwendet werden sollen, sollten Sie @Transient
Und nicht das JavaSE-Schlüsselwort transient
verwenden Das Ausführen auf anderen VMs kann Zeit sparen, um die Berechnung erneut durchzuführen.
Ich werde versuchen, die Frage nach dem "Warum" zu beantworten. Stellen Sie sich eine Situation vor, in der Sie eine riesige Datenbank mit vielen Spalten in einer Tabelle haben und Ihr Projekt/System Tools verwendet, um Entitäten aus der Datenbank zu generieren. (Hibernate hat diese, etc ...) Nehmen wir nun an, dass Sie für Ihre Geschäftslogik ein bestimmtes Feld benötigen, das NICHT beibehalten werden soll. Sie müssen Ihre Entität auf eine bestimmte Weise "konfigurieren". Während das Schlüsselwort "Transient" für ein Objekt ausgeführt wird - wie es sich in einer Java Sprache verhält - wurde der @Transient nur zur Beantwortung von Aufgaben entwickelt, die nur Persistenzaufgaben betreffen.