Mengapa JPA memiliki anotasi @Transient?

283

Java memiliki transientkata kunci. Mengapa JPA memiliki @Transientalih - alih hanya menggunakan kata kunci java yang sudah ada?

deamon
sumber

Jawaban:

455

transientKata kunci Java digunakan untuk menyatakan bahwa suatu bidang tidak harus diserialisasi, sedangkan @Transientanotasi JPA digunakan untuk menunjukkan bahwa suatu bidang tidak akan bertahan dalam database, yaitu semantiknya berbeda.

Jawher
sumber
3
Ya, semantiknya berbeda. Tetapi mengapa JPA dirancang dengan cara ini?
Dilum Ranatunga
1
Tidak yakin saya mengerti Anda, tetapi lihat jawaban "Pascal Thivent";)
Jawher
30
Ini berguna karena Anda mungkin tidak ingin menyimpan data dalam database, tetapi Anda ingin menyimpannya dalam sistem JPA Chaching yang menggunakan serialisasi untuk menyimpan / mengembalikan entitas.
Kdeveloper
1
"Sistem Caching JPA" apa yang menggunakan serialisasi untuk penyimpanan / pengembalian entitas? implementasi JPA dapat men-cache objek dengan cara apa pun yang mereka inginkan, dan serialisasi tidak masuk ke dalamnya.
DataNucleus
@Jawher, di sini untuk transient not presistant berarti tidak mempresisi nilai apa pun atau akan memasukkan nilai default untuk atribut itu.
Satish Sharma
115

Karena mereka memiliki arti yang berbeda. The @Transientpenjelasan memberitahu penyedia JPA untuk tidak bertahan apapun (non transient) atribut. Yang lain memberitahu kerangka serialisasi untuk tidak membuat serialisasi atribut. Anda mungkin ingin memiliki @Transientproperti dan masih membuat cerita bersambung.

Thivent Pascal
sumber
Terima kasih atas jawaban Pascal. Sebagai catatan dari komentar Anda: "Anda mungkin ingin memiliki properti @Transient dan masih membuat cerita bersambung." (Itulah yang saya cari) Saya juga ingin menambahkan bahwa yang sebaliknya tidak benar. Jika seseorang menetapkan variabel sebagai sementara, maka Anda tidak dapat mempertahankannya.
jfajunior
96

Seperti yang dikatakan orang lain, @Transientdigunakan untuk menandai bidang yang tidak boleh dipertahankan. Perhatikan contoh singkat ini:

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);
    }
}

Ketika kelas ini diumpankan ke JPA, ia bertahan genderdan idtetapi tidak mencoba untuk bertahan metode boolean pembantu - tanpa @Transientsistem yang mendasarinya akan mengeluh bahwa kelas Entitas Personhilang setMale()dan setFemale()metode dan dengan demikian tidak akan bertahan Personsama sekali.

Esko
sumber
@ psp dapatkah Anda menjelaskan lebih lanjut tentang mengapa / bagaimana hal itu dapat menyebabkan perilaku yang tidak ditentukan? Terima kasih!
taiduckman
@ 40Plot spesifikasi menyatakan begitu
psp
7
Ini harus IMHO jawaban yang diterima karena jauh lebih menjelaskan bahwa yang diterima saat ini ...
Honza Zidek
53

Tujuannya berbeda:

Kata transientkunci dan @Transientanotasi memiliki dua tujuan yang berbeda: satu berurusan dengan serialisasi dan satu berurusan dengan kegigihan . Sebagai programmer, kita sering menggabungkan dua konsep ini menjadi satu, tetapi ini umumnya tidak akurat. Ketekunan mengacu pada karakteristik negara yang hidup lebih lama dari proses yang menciptakannya. Serialisasi di Jawa mengacu pada proses pengkodean / decoding keadaan objek sebagai aliran byte.

Kata transientkunci adalah kondisi yang lebih kuat daripada @Transient:

Jika bidang menggunakan transientkata kunci, bidang itu tidak akan diserialisasi ketika objek dikonversi ke aliran byte. Selain itu, karena JPA memperlakukan bidang yang ditandai dengan transientkata kunci sebagai @Transientanotasi, bidang tersebut tidak akan bertahan oleh JPA juga.

Di sisi lain, bidang yang dianotasi @Transientsaja akan dikonversi ke aliran byte saat objek tersebut diserialisasi, tetapi tidak akan bertahan oleh JPA. Karenanya, transientkata kunci adalah kondisi yang lebih kuat daripada @Transientanotasi.

Contoh

Ini menimbulkan pertanyaan: Mengapa ada orang yang ingin membuat serial suatu bidang yang tidak bertahan ke database aplikasi? Kenyataannya adalah bahwa serialisasi digunakan untuk lebih dari sekedar kegigihan . Dalam aplikasi Enterprise Java perlu ada mekanisme untuk bertukar objek antara komponen yang didistribusikan ; serialisasi menyediakan protokol komunikasi umum untuk menangani hal ini. Dengan demikian, suatu bidang dapat menyimpan informasi penting untuk tujuan komunikasi antar-komponen; tetapi bidang yang sama itu mungkin tidak memiliki nilai dari perspektif kegigihan.

Misalnya, anggap algoritma pengoptimalan dijalankan di server, dan anggap algoritma ini membutuhkan waktu beberapa jam untuk menyelesaikannya. Bagi seorang klien, memiliki rangkaian solusi paling baru adalah penting. Jadi, klien dapat berlangganan ke server dan menerima pembaruan berkala selama fase eksekusi algoritma. Pembaruan ini disediakan menggunakan ProgressReportobjek:

@Entity
public class ProgressReport implements Serializable{

    private static final long serialVersionUID = 1L;

    @Transient
    long estimatedMinutesRemaining;
    String statusMessage;
    Solution currentBestSolution;

}

The Solutionkelas akan terlihat seperti ini:

@Entity
public class Solution implements Serializable{

    private static final long serialVersionUID = 1L;

    double[][] dataArray;
    Properties properties;
}

Server tetap masing ProgressReport- masing ke database-nya. Server tidak peduli untuk bertahan estimatedMinutesRemaining, tetapi klien tentu peduli dengan informasi ini. Oleh karena itu, estimatedMinutesRemainingdijelaskan menggunakan @Transient. Ketika final Solutionditemukan oleh algoritma, itu dipertahankan oleh JPA secara langsung tanpa menggunakan a ProgressReport.

Austin D
sumber
1
Jika mereka benar-benar berbeda kepedulian, pasti ada kata lain yang menangkap nuansa. Mengapa istilah itu berlebihan? Sebagai saran pemula @Unpersisted,.
Dilum Ranatunga
4
Saya pribadi suka @Ephemeral. Menurut Merriam Webster: Ketika ephemeral pertama kali dicetak dalam bahasa Inggris pada 1600-an, "itu adalah istilah ilmiah yang diterapkan pada demam jangka pendek, dan kemudian, untuk organisme (seperti serangga dan bunga) dengan masa hidup yang sangat singkat. Segera setelah itu , ia memperoleh pengertian luas yang merujuk pada apa pun yang berlalu sebentar dan berumur pendek (seperti dalam "kesenangan sesaat"). "
Austin D
1
Apa yang saya juga suka tentang jawaban ini adalah bahwa ia menyebutkan bahwa JPA menganggap transientbidang secara implisit memiliki @Transientanotasi. Jadi, jika Anda menggunakan transientkata kunci untuk mencegah serialisasi suatu bidang maka itu tidak akan berakhir di basis data juga.
neXus
17

Jika Anda hanya ingin bidang tidak bertahan, baik transient dan @Transient berfungsi. Tetapi pertanyaannya adalah mengapa @ Trransient sejak transient sudah ada.

Karena bidang @Transient masih akan mendapatkan serial!

Misalkan Anda membuat entitas, melakukan perhitungan yang menghabiskan CPU untuk mendapatkan hasil dan hasil ini tidak akan disimpan dalam database. Tetapi Anda ingin mengirim entitas ke aplikasi Java lain untuk digunakan oleh JMS, maka Anda harus menggunakan @Transient, bukan kata kunci JavaSE transient. Jadi penerima yang menggunakan VM lain dapat menghemat waktu mereka untuk menghitung ulang lagi.

Sheng
sumber
dapatkah Anda memberikan contoh untuk membuatnya lebih jelas?
Harsh Kanakhara
apakah ada penjelasan yang akan diperlakukan jpa sebagai sementara tetapi jackson tidak akan melakukannya?
Kalpesh Soni
0

Saya akan mencoba menjawab pertanyaan "mengapa". Bayangkan situasi di mana Anda memiliki database besar dengan banyak kolom dalam sebuah tabel, dan proyek / sistem Anda menggunakan alat untuk menghasilkan entitas dari database. (Hibernate memiliki itu, dll ...) Sekarang, anggaplah dengan logika bisnis Anda, Anda perlu bidang tertentu TIDAK untuk bertahan. Anda harus "mengkonfigurasi" entitas Anda dengan cara tertentu. Sementara kata kunci Transient berfungsi pada objek - karena berperilaku dalam bahasa java, @Transient hanya dirancang untuk menjawab tugas-tugas yang hanya berkaitan dengan tugas-tugas yang bertahan lama.

Dima R.
sumber