Antworten:
Das transient
Schlüsselwort von Java wird verwendet, um @Transient
anzugeben, dass ein Feld nicht serialisiert werden soll, während die Annotation von JPA verwendet wird, um anzugeben, dass ein Feld nicht in der Datenbank beibehalten werden soll, dh ihre Semantik ist unterschiedlich.
Weil sie unterschiedliche Bedeutungen haben. Die @Transient
Anmerkung weist den JPA-Anbieter an, kein (Nicht- transient
) Attribut beizubehalten . Der andere weist das Serialisierungsframework an, ein Attribut nicht zu serialisieren. Möglicherweise möchten Sie eine @Transient
Eigenschaft haben und diese dennoch serialisieren.
Wie andere gesagt haben, @Transient
wird verwendet, um Felder zu markieren, die nicht beibehalten werden sollten. 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 an die JPA weitergeleitet wird, behält sie die booleschen Hilfsmethoden bei gender
und id
versucht nicht , sie beizubehalten - ohne dass @Transient
das zugrunde liegende System sich darüber beschweren würde, dass die Entity-Klasse und Methoden Person
fehlen und daher überhaupt nicht bestehen bleiben .setMale()
setFemale()
Person
Zweck ist anders:
Das transient
Schlüsselwort und die @Transient
Anmerkung dienen zwei unterschiedlichen Zwecken: einem der Serialisierung und einem der Persistenz . Als Programmierer verbinden wir diese beiden Konzepte oft zu einem, aber dies ist im Allgemeinen nicht korrekt. Beharrlichkeit bezieht sich auf die Eigenschaft des Staates, die den Prozess überlebt, der ihn geschaffen hat. Die Serialisierung in Java bezieht sich auf den Prozess des Codierens / Decodierens des Status eines Objekts als Bytestream.
Das transient
Schlüsselwort ist eine stärkere Bedingung als @Transient
:
Wenn ein Feld das transient
Schlüsselwort verwendet, wird dieses Feld nicht serialisiert, wenn das Objekt in einen Bytestream konvertiert wird. Da JPA Felder, die mit dem transient
Schlüsselwort markiert sind, als mit @Transient
Anmerkungen versehen behandelt, wird das Feld auch von JPA nicht beibehalten.
Auf der anderen Seite, kommentierten Felder @Transient
allein werden zu einem Byte - Strom umgewandelt werden , wenn das Objekt serialisiert wird, aber es wird nicht von JPA beibehalten werden. Daher ist das transient
Schlüsselwort eine stärkere Bedingung als die @Transient
Anmerkung.
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 Austausch von Objekten zwischen verteilten Komponenten vorhanden sein . Die Serialisierung bietet ein gemeinsames Kommunikationsprotokoll, um dies zu handhaben. Somit kann ein Feld kritische Informationen zum Zweck der Kommunikation zwischen Komponenten enthalten; Das gleiche Feld hat jedoch aus Sicht der Persistenz möglicherweise keinen Wert.
Angenommen, ein Optimierungsalgorithmus wird auf einem Server ausgeführt, und dieser Algorithmus dauert mehrere Stunden. Für einen Kunden ist es wichtig, über die aktuellsten Lösungen zu verfügen. So kann ein Client den Server abonnieren und während der Ausführungsphase des Algorithmus regelmäßige Aktualisierungen erhalten. Diese Updates werden über das ProgressReport
Objekt bereitgestellt :
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
Die Solution
Klasse könnte folgendermaßen aussehen:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Der Server behält jeweils ProgressReport
seine Datenbank bei. Der Server möchte nicht bestehen bleiben estimatedMinutesRemaining
, aber der Client kümmert sich auf jeden Fall um diese Informationen. Daher wird das estimatedMinutesRemaining
mit kommentiert @Transient
. Wenn das Finale Solution
vom Algorithmus lokalisiert wird, wird es von JPA direkt ohne Verwendung von a beibehalten ProgressReport
.
@Unpersisted
.
@Ephemeral
. Laut Merriam Webster: Als Ephemeral im 17. Jahrhundert erstmals in englischer Sprache gedruckt wurde, "war es ein wissenschaftlicher Begriff, der für kurzfristiges Fieber und später für Organismen (wie Insekten und Blumen) mit sehr kurzen Lebensdauern verwendet wurde. Bald danach , es erhielt einen erweiterten Sinn, der sich auf alles bezieht, was flüchtig und kurzlebig ist (wie in "vergänglichen Freuden"). "
transient
Felder als implizit mit der @Transient
Anmerkung versehen betrachtet. Wenn Sie also das transient
Schlüsselwort verwenden, um die Serialisierung eines Felds zu verhindern, wird es auch nicht in der Datenbank gespeichert.
Wenn Sie nur möchten, dass ein Feld nicht beibehalten wird, funktionieren sowohl vorübergehend als auch vorübergehend . Die Frage ist jedoch, warum @Transient da transient bereits existiert.
Weil das @ Transient-Feld immer noch serialisiert wird!
Angenommen, Sie erstellen eine Entität und führen einige CPU-belastende Berechnungen 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, um sie von JMS zu verwenden, sollten Sie @Transient
nicht das JavaSE-Schlüsselwort verwenden transient
. So können die Empfänger, die auf anderen VMs ausgeführt werden, Zeit sparen, um erneut zu berechnen.
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 usw.) Nehmen wir nun an, dass Sie nach Ihrer 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 funktioniert, da es sich in einer Java-Sprache verhält, wurde @Transient nur zur Beantwortung der Aufgaben entwickelt, die sich nur auf Persistenzaufgaben beziehen.