web-dev-qa-db-ger.com

Warum hat JPA eine @ Transient-Anmerkung?

Java hat das Schlüsselwort transient. Warum hat JPA @Transient anstatt einfach das bereits vorhandene Schlüsselwort Java?

259
deamon

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.

405
Jawher

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.

108
Pascal Thivent

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.

89
Esko

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.

44
Austin D

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.

17
Sheng.W

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.

0
Dima R.