Risposte:
La transient
parola chiave Java viene utilizzata per indicare che un campo non deve essere serializzato, mentre l' @Transient
annotazione di JPA viene utilizzata per indicare che un campo non deve essere persistito nel database, vale a dire che la loro semantica è diversa.
Perché hanno significati diversi. L' @Transient
annotazione indica al provider JPA di non persistere alcun transient
attributo (non ). L'altro dice al framework di serializzazione di non serializzare un attributo. Potresti voler avere una @Transient
proprietà e comunque serializzarla.
Come altri hanno già detto, @Transient
viene utilizzato per contrassegnare i campi che non devono essere mantenuti. Considera questo breve esempio:
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);
}
}
Quando questa classe è alimentato all'APP, persiste la gender
e id
ma non tenta di persistere metodi booleani helper - senza @Transient
il sistema sottostante si lamentano che la classe Entity Person
è mancante setMale()
e setFemale()
metodi e quindi non sarebbe persistere Person
affatto.
Lo scopo è diverso:
La transient
parola chiave e l' @Transient
annotazione hanno due scopi diversi: uno si occupa della serializzazione e uno si occupa della persistenza . Come programmatori, spesso sposiamo questi due concetti in uno solo, ma questo non è accurato in generale. La persistenza si riferisce alla caratteristica dello stato che sopravvive al processo che l'ha creata. La serializzazione in Java si riferisce al processo di codifica / decodifica dello stato di un oggetto come flusso di byte.
La transient
parola chiave è una condizione più forte di @Transient
:
Se un campo utilizza la transient
parola chiave, quel campo non verrà serializzato quando l'oggetto viene convertito in un flusso di byte. Inoltre, poiché l'APP considera i campi contrassegnati con la transient
parola chiave come aventi l' @Transient
annotazione, neanche l'APP persevererà nel campo.
D'altra parte, i campi annotati @Transient
da soli verranno convertiti in un flusso di byte quando l'oggetto è serializzato, ma non verrà persistito da JPA. Pertanto, la transient
parola chiave è una condizione più forte @Transient
dell'annotazione.
Esempio
Ciò pone la domanda: perché qualcuno dovrebbe voler serializzare un campo che non è persistito nel database dell'applicazione? La realtà è che la serializzazione viene utilizzata per qualcosa di più della semplice persistenza . In un'applicazione Java Enterprise deve esserci un meccanismo per scambiare oggetti tra componenti distribuiti ; la serializzazione fornisce un protocollo di comunicazione comune per gestirlo. Pertanto, un campo può contenere informazioni critiche ai fini della comunicazione tra componenti; ma quello stesso campo potrebbe non avere alcun valore dal punto di vista della persistenza.
Ad esempio, supponiamo che un algoritmo di ottimizzazione venga eseguito su un server e supponga che questo algoritmo richieda diverse ore per essere completato. Per un cliente è importante disporre delle soluzioni più aggiornate. Pertanto, un client può iscriversi al server e ricevere aggiornamenti periodici durante la fase di esecuzione dell'algoritmo. Questi aggiornamenti vengono forniti utilizzando l' ProgressReport
oggetto:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
La Solution
classe potrebbe apparire così:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Il server persiste ciascuno ProgressReport
nel suo database. Il server non si preoccupa di persistere estimatedMinutesRemaining
, ma il client ha sicuramente a cuore queste informazioni. Pertanto, estimatedMinutesRemaining
viene annotato usando @Transient
. Quando la finale Solution
viene individuata dall'algoritmo, viene mantenuta direttamente da JPA senza utilizzare a ProgressReport
.
@Unpersisted
.
@Ephemeral
. Secondo Merriam Webster: Quando l'effimero fu stampato per la prima volta in inglese nel 1600, "era un termine scientifico applicato alle febbri a breve termine e, successivamente, agli organismi (come insetti e fiori) con una durata della vita molto breve. Poco dopo , acquisì un senso esteso riferendosi a qualsiasi cosa fugace e di breve durata (come nei "piaceri effimeri"). "
transient
campi implicitamente aventi l' @Transient
annotazione. Quindi, se si utilizza la transient
parola chiave per impedire la serializzazione di un campo, non finirà nemmeno nel database.
Se vuoi solo che un campo non sia persistente, funzionano sia i transitori che i @Transient . Ma la domanda è perché @Transient da quando esiste il transitorio .
Perché il campo @Transient verrà comunque serializzato!
Supponiamo di creare un'entità, facendo alcuni calcoli che consumano CPU per ottenere un risultato e questo risultato non verrà salvato nel database. Ma vuoi inviare l'entità ad altre applicazioni Java da utilizzare da JMS, quindi dovresti usare @Transient
, non la parola chiave JavaSE transient
. Pertanto, i ricevitori in esecuzione su altre macchine virtuali possono risparmiare tempo per ricalcolare di nuovo.
Proverò a rispondere alla domanda "perché". Immagina una situazione in cui hai un enorme database con molte colonne in una tabella e il tuo progetto / sistema usa strumenti per generare entità dal database. (Hibernate ha quelli, ecc ...) Ora, supponiamo che secondo la vostra logica aziendale sia necessario che un particolare campo NON sia persistente. Devi "configurare" la tua entità in un modo particolare. Mentre la parola chiave Transient funziona su un oggetto, poiché si comporta in un linguaggio java, @Transient è progettato solo per rispondere alle attività che riguardano solo le attività di persistenza.