2010-01-28 11 views

Antwort

315

Java transient Schlüsselwort wird verwendet, um anzuzeigen, dass ein Feld nicht serialisiert werden, wohingegen der PPV @Transient Anmerkung verwendet wird, um anzuzeigen, dass ein Feld nicht in der Datenbank werden soll beibehalten, das heißt ihre Semantik sind unterschiedlich.

+1

Ja, die Semantik ist unterschiedlich. Aber warum wurde JPA so entworfen? –

+1

Ich bin mir nicht sicher, ob ich Sie verstehe, aber werfen Sie einen Blick auf die Antwort von "Pascal Thivent";) – Jawher

+18

Dies ist praktisch, weil Sie die Daten möglicherweise nicht in der Datenbank speichern möchten, sie aber in der JPA speichern möchten Chaching-System, das die Serialisierung für das Speichern/Wiederherstellen von Entitäten verwendet. – Kdeveloper

96

Weil sie unterschiedliche Bedeutungen haben. Die Annotation @Transient weist den JPA-Anbieter an, keine Attribute (nicht) zu erhalten. Die andere Anweisung weist das Serialisierungsframework an, ein Attribut nicht zu serialisieren. Möglicherweise möchten Sie eine @Transient-Eigenschaft haben und diese weiterhin serialisieren.

71

Wie andere bereits gesagt haben, wird @Transient zur Markierung von Feldern verwendet, die nicht persistiert 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 PPV zugeführt wird, es bleibt die gender und id aber nicht versucht, die Helfer boolean Methoden bestehen bleiben - ohne @Transient das zugrundeliegende System würde sich beschweren, dass die Entity-Klasse Person fehlt setMale() und setFemale() Methoden und somit würde Person überhaupt nicht bestehen bleiben.

+0

@psp können Sie mehr darüber erklären, warum/wie es unspezifisches Verhalten verursachen könnte? Vielen Dank! – 40Plot

+0

@ 40Plot die Spezifikation Staaten so – psp

+4

Dies sollte IMHO die angenommene Antwort sein, da es viel mehr erklärt, dass die aktuelle akzeptiert ... –

11

Wenn Sie nur ein Feld wollen nicht beibehalten lassen, sowohl vorübergehende und @Transient Arbeit. Aber die Frage ist, warum @Transient seit transient bereits existiert.

Da @Transient Feld wird immer noch serialisiert werden!

Angenommen, Sie erstellen eine Entität, führen eine CPU-aufwändige Berechnung durch, um ein Ergebnis zu erhalten, und 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 verwenden. Daher können die Empfänger, die auf anderen VMs laufen, ihre Zeit für die erneute Berechnung speichern.

+0

können Sie bitte Beispiel zur Verfügung stellen, um es klarer zu machen? –

0

Ich werde versuchen, die Frage zu beantworten, "warum". Stellen Sie sich eine Situation vor, in der Sie eine riesige Datenbank mit vielen Spalten in einer Tabelle haben und Ihr Projekt/System Werkzeuge verwendet, um Entitäten aus der Datenbank zu generieren. (Hibernate hat diese, etc ...) Nehmen wir nun an, dass Sie aufgrund Ihrer Geschäftslogik ein bestimmtes Feld benötigen, das NICHT beibehalten werden soll. Sie müssen Ihre Entität auf eine bestimmte Art "konfigurieren". Während das Transient-Schlüsselwort auf einem Objekt funktioniert - da es sich in einer Java-Sprache verhält, wurde mit @Transient nur die Aufgabe beantwortet, die nur Persistenzaufgaben betrifft.

26

Zweck ist anders:

Die transient Schlüsselwort und @Transient Anmerkung haben zwei verschiedene Zwecke: eine befasst sich mit Serialisierung und man sich mit Persistenz. Als Programmierer heiraten wir diese beiden Konzepte oft zu einem, aber das ist im Allgemeinen nicht korrekt. Persistence bezieht sich auf die Eigenschaft des Zustands, die den Prozess überlebt, der es erstellt hat.Serialization in Java bezieht sich auf den Prozess der Codierung/Decodierung des Zustands eines Objekts als Byte-Stream.

Das transient Schlüsselwort ist eine stärkere Bedingung als @Transient:

Wenn ein Feld das transient Schlüsselwort verwendet, wird dieses Feld nicht serialisiert werden, wenn das Objekt in einem Byte-Strom umgewandelt wird. Da JPA außerdem Felder behandelt, die mit dem Schlüsselwort transient als @Transient-Annotation gekennzeichnet sind, wird das Feld auch nicht von JPA beibehalten.

Auf der anderen Seite, Felder @Transient allein kommentierten wird zu einem Byte-Strom umgewandelt werden, wenn das Objekt serialisiert, aber es wird nicht von JPA beibehalten werden. Aus diesem Grund ist das Schlüsselwort transient eine stärkere Bedingung als die Annotation.

Beispiel

Dies wirft die Frage auf: Warum sollte jemand ein Feld serialisiert werden, das nicht zu der Datenbank der Anwendung beibehalten wird? Die Realität ist, dass Serialisierung für mehr als nur Persistenz verwendet wird. In einer Enterprise Java-Anwendung muss ein Mechanismus zum Austausch von Objekten zwischen verteilten Komponenten; Serialisierung stellt ein gemeinsames Kommunikationsprotokoll bereit, um dies zu handhaben. Somit kann ein Feld kritische Information für den Zweck der Kommunikation zwischen Komponenten enthalten; aber dasselbe Feld kann aus Persistenzperspektive keinen Wert haben.

Angenommen, ein Optimierungsalgorithmus wird auf einem Server ausgeführt und es wird angenommen, dass dieser Algorithmus mehrere Stunden benötigt. 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 unter Verwendung bereitgestellt, um die ProgressReport Objekt:

@Entity 
public class ProgressReport implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    @Transient 
    long estimatedMinutesRemaining; 
    String statusMessage; 
    Solution currentBestSolution; 

} 

Die Solution Klasse könnte wie folgt aussehen:

@Entity 
public class Solution implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    double[][] dataArray; 
    Properties properties; 
} 

Der Server jedes ProgressReport seiner Datenbank weiterhin besteht. Der Server kümmert sich nicht um estimatedMinutesRemaining, aber der Client kümmert sich sicherlich um diese Informationen. Daher wird die estimatedMinutesRemaining mit @Transient kommentiert. Wenn der letzte Solution durch den Algorithmus gefunden wird, wird er direkt von JPA beibehalten, ohne eine ProgressReport zu verwenden.

+0

Wenn sie tatsächlich unterschiedliche Anliegen sind, gibt es sicherlich ein anderes Wort, das die Nuancen einfängt. Warum überladen Sie den Begriff? Als Startvorschlag "@ Unversichert". –

+1

Ich persönlich mag '@ Ephemeral'. Laut Merriam Webster: Als die Ephemeren im 17. Jahrhundert zum ersten Mal in englischer Sprache gedruckt wurden, "war es ein wissenschaftlicher Ausdruck für kurzzeitiges Fieber und später für Organismen (wie Insekten und Blumen) mit sehr kurzer Lebensdauer , er erwarb einen erweiterten Sinn, der sich auf alles Flüchtige und Kurzlebige bezieht (wie in "ephemeren Vergnügungen"). " –

+0

Sehr gute Erklärung! – GOXR3PLUS

Verwandte Themen