2010-01-28 18 views

risposta

315

transient parola chiave di Java viene utilizzato per indicare che un campo non deve essere serializzato, mentre @Transient annotazioni dell'APP viene utilizzato per indicare che un campo non è quello di essere mantenuta nel database, vale a dire la loro semantica sono diversi.

+1

Sì, la semantica è diversa. Ma perché l'JPA è stato progettato in questo modo? –

+1

Non sono sicuro che ti capisco, ma dai un'occhiata alla risposta di "Pascal Thivent";) – Jawher

+18

Questo è utile perché potresti non voler memorizzare i dati nel database, ma vuoi memorizzarli nell'APP Chaching system che utilizza la serializzazione per memorizzare/ripristinare entità. – Kdeveloper

96

Perché hanno significati diversi. L'annotazione @Transient indica al provider JPA di non persistere alcun attributo (non transient). L'altro dice al framework di serializzazione di non serializzare un attributo. Si potrebbe desiderare di avere una proprietà @Transient e ancora serializzarla.

71

Come altri hanno già detto, @Transient viene utilizzato per contrassegnare i campi che non devono essere mantenuti. Considerate 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 alla APP, persiste il gender e id, ma non cerca di persistere i helper metodi booleani - senza @Transient il sistema sottostante avrebbe lamentano che la classe Entity Person mancano i metodi setMale() e setFemale() e quindi non dovrebbero persistere Person.

+0

@psp puoi spiegare di più sul perché/come potrebbe causare un comportamento non specificato? Grazie! – 40Plot

+0

@ 40Plot la specifica dichiara così – psp

+4

Questo dovrebbe essere IMHO la risposta accettata in quanto è molto più esplicativo che l'attuale accettato ... –

11

Se si desidera solo un campo non verrà persistito, sia transitorio e @Transient lavoro. Ma la domanda è perché @Transient dal transitorio esiste già.

Perché il campo @Transient verrà ancora serializzato!

Supponiamo di creare un'entità, eseguendo alcuni calcoli che consumano CPU per ottenere un risultato e questo risultato non verrà salvato nel database. Ma si desidera inviare l'entità ad altre applicazioni Java da utilizzare con JMS, quindi utilizzare @Transient, non la parola chiave JavaSE transient. Quindi i ricevitori in esecuzione su altre macchine virtuali possono risparmiare di nuovo il loro tempo per ricalcolare.

+0

puoi per favore fornire un esempio per renderlo più chiaro? –

0

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 utilizza strumenti per generare entità dal database. (Hibernate ha quelli, ecc ...) Ora, supponiamo che dalla tua logica di business tu abbia bisogno di un campo particolare che NON sia persistente. Devi "configurare" la tua entità in un modo particolare. Mentre la parola chiave transitoria funziona su un oggetto, poiché si comporta all'interno di un linguaggio java, @Transient è progettato solo per rispondere alle attività che riguardano solo le attività di persistenza.

26

scopo è diverso:

Il transient parola chiave e @Transient annotazione hanno due scopi differenti: uno si occupa di serializzazione e uno si occupa di persistenza. Come programmatori, spesso sposiamo questi due concetti in uno solo, ma questo non è accurato in generale. Persistence fa riferimento alla caratteristica di stato che sopravvive al processo che lo ha creato.Serialization in Java fa riferimento al processo di codifica/decodifica dello stato di un oggetto come flusso di byte.

Il transient parola chiave è una condizione più forte di @Transient:

Se un campo utilizza la parola chiave transient, quel campo non verrà serializzato quando l'oggetto viene convertito in un flusso di byte. Inoltre, poiché il JPA considera i campi contrassegnati con la parola chiave transient con l'annotazione @Transient, il campo non verrà mantenuto nemmeno da JPA.

D'altra parte, i campi annotati @Transient solo volontà essere convertito in un flusso di byte quando l'oggetto è serializzato, ma non sarà persisteva da APP. Pertanto, la parola chiave transient è una condizione più forte rispetto all'annotazione @Transient.

Esempio

Questo fa sorgere una domanda: Perché qualcuno dovrebbe voler serializzare un campo che non viene mantenuto al database dell'applicazione? La realtà è che la serializzazione viene utilizzata per qualcosa di più della semplice persistenza. In un'applicazione Enterprise Java è necessario che sia un meccanismo per lo scambio di 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 inter-componente; ma quello stesso campo potrebbe non avere alcun valore da una prospettiva di persistenza.

Ad esempio, supponiamo che un algoritmo di ottimizzazione venga eseguito su un server e supponiamo che questo algoritmo impieghi diverse ore per essere completato. Per un cliente, avere la serie più aggiornata di soluzioni è importante. Quindi, un client può iscriversi al server e ricevere aggiornamenti periodici durante la fase di esecuzione dell'algoritmo. Questi aggiornamenti vengono forniti utilizzando l'oggetto ProgressReport:

@Entity 
public class ProgressReport implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    @Transient 
    long estimatedMinutesRemaining; 
    String statusMessage; 
    Solution currentBestSolution; 

} 

La classe Solution potrebbe assomigliare a questo:

@Entity 
public class Solution implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    double[][] dataArray; 
    Properties properties; 
} 

Il server persiste ogni ProgressReport al suo database. Il server non si preoccupa di persistere estimatedMinutesRemaining, ma al cliente interessano sicuramente queste informazioni. Pertanto, lo estimatedMinutesRemaining viene annotato utilizzando @Transient. Quando l'ultimo Solution si trova all'algoritmo, viene mantenuto da JPA direttamente senza utilizzare uno ProgressReport.

+0

Se in realtà sono preoccupazioni diverse, sicuramente esiste una parola diversa che cattura le sfumature. Perché sovraccaricare il termine? Come suggerimento di base, '@ Unpersisted'. –

+1

Personalmente mi piace '@ 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, in seguito, agli organismi (come insetti e fiori) con durata molto breve. , ha acquisito un senso esteso riferendosi a qualsiasi cosa fugace e di breve durata (come in "piaceri effimeri"). " –

+0

Ottima spiegazione! – GOXR3PLUS

Problemi correlati