Warum hat JPA eine @ Transient-Annotation?


Antworten:


455

Das transientSchlüsselwort von Java wird verwendet, um @Transientanzugeben, 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.


3
Ja, die Semantik ist unterschiedlich. Aber warum wurde JPA so konzipiert?
Dilum Ranatunga

1
Ich bin mir nicht sicher, ob ich dich verstehe, aber sieh dir die Antwort von "Pascal Thivent" an;)
Jawher

30
Dies ist praktisch, da Sie die Daten möglicherweise nicht in der Datenbank speichern möchten, sie jedoch im JPA-Chaching-System speichern möchten, das die Serialisierung zum Speichern / Wiederherstellen von Entitäten verwendet.
Kdeveloper

1
Welches "JPA-Caching-System" verwendet die Serialisierung zum Speichern / Wiederherstellen von Entitäten? Eine JPA-Implementierung kann ein Objekt nach Belieben zwischenspeichern, und die Serialisierung wird nicht ausgeführt.
DataNucleus

@Jawher, hier bedeutet für vorübergehend nicht vorhanden, dass kein Wert vorhanden ist, oder es wird ein Standardwert für dieses Attribut eingefügt.
Satish Sharma

115

Weil sie unterschiedliche Bedeutungen haben. Die @TransientAnmerkung 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 @TransientEigenschaft haben und diese dennoch serialisieren.


Danke für die Antwort Pascal. Als Anmerkung aus Ihrem Kommentar: "Möglicherweise möchten Sie eine @ Transient-Eigenschaft haben und diese trotzdem serialisieren." (Das war es, wonach ich gesucht habe) Ich möchte auch hinzufügen, dass das Gegenteil nicht der Fall ist. Wenn man eine Variable als transient festlegt, kann man sie nicht beibehalten.
23.

96

Wie andere gesagt haben, @Transientwird 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 genderund idversucht nicht , sie beizubehalten - ohne dass @Transientdas zugrunde liegende System sich darüber beschweren würde, dass die Entity-Klasse und Methoden Personfehlen und daher überhaupt nicht bestehen bleiben .setMale()setFemale()Person


@psp Kannst du mehr darüber erklären, warum / wie es zu nicht spezifiziertem Verhalten führen kann? Vielen Dank!
Taiduckman

@ 40Plot die Spezifikation Zustände so
psp

7
Dies sollte meiner Meinung nach die akzeptierte Antwort sein, da es viel mehr erklärt, dass die aktuell akzeptierte ...
Honza Zidek

53

Zweck ist anders:

Das transientSchlüsselwort und die @TransientAnmerkung 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 transientSchlüsselwort ist eine stärkere Bedingung als @Transient:

Wenn ein Feld das transientSchlüsselwort verwendet, wird dieses Feld nicht serialisiert, wenn das Objekt in einen Bytestream konvertiert wird. Da JPA Felder, die mit dem transientSchlüsselwort markiert sind, als mit @TransientAnmerkungen versehen behandelt, wird das Feld auch von JPA nicht beibehalten.

Auf der anderen Seite, kommentierten Felder @Transientallein werden zu einem Byte - Strom umgewandelt werden , wenn das Objekt serialisiert wird, aber es wird nicht von JPA beibehalten werden. Daher ist das transientSchlüsselwort eine stärkere Bedingung als die @TransientAnmerkung.

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 ProgressReportObjekt bereitgestellt :

@Entity
public class ProgressReport implements Serializable{

    private static final long serialVersionUID = 1L;

    @Transient
    long estimatedMinutesRemaining;
    String statusMessage;
    Solution currentBestSolution;

}

Die SolutionKlasse 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 ProgressReportseine 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 estimatedMinutesRemainingmit kommentiert @Transient. Wenn das Finale Solutionvom Algorithmus lokalisiert wird, wird es von JPA direkt ohne Verwendung von a beibehalten ProgressReport.


1
Wenn es sich tatsächlich um unterschiedliche Anliegen handelt, gibt es sicherlich ein anderes Wort, das die Nuancen erfasst. Warum den Begriff überladen? Als Startervorschlag @Unpersisted.
Dilum Ranatunga

4
Ich persönlich mag @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"). "
Austin D

1
Was mir an dieser Antwort auch gefällt, ist, dass darin erwähnt wird, dass JPA transientFelder als implizit mit der @TransientAnmerkung versehen betrachtet. Wenn Sie also das transientSchlüsselwort verwenden, um die Serialisierung eines Felds zu verhindern, wird es auch nicht in der Datenbank gespeichert.
neXus

17

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 @Transientnicht 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.


Können Sie bitte ein Beispiel geben, um es klarer zu machen?
Harte Kanakhara

Gibt es eine Anmerkung, die jpa als vorübergehend behandelt, Jackson jedoch nicht?
Kalpesh Soni

0

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.