Odpowiedzi:
Słowo transient
kluczowe Javy służy do oznaczania, że pole nie ma być serializowane, natomiast @Transient
adnotacja JPA służy do wskazania, że pole nie ma być utrwalane w bazie danych, tj. Ich semantyka jest inna.
Ponieważ mają różne znaczenia. @Transient
Adnotacja informuje dostawcę JPA nie utrzymują żadnego (nie transient
) atrybut. Drugi informuje środowisko serializacji, aby nie serializowało atrybutu. Możesz chcieć mieć @Transient
właściwość i nadal ją serializować.
Jak powiedzieli inni, @Transient
służy do oznaczania pól, których nie należy utrwalać. Rozważ ten krótki przykład:
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);
}
}
Gdy ta klasa jest podawana do JPA, trwa gender
i id
nie próbuje utrwalić metod pomocniczych boolean - bez @Transient
systemu bazowego narzekałby, że Person
brakuje klasy Entity setMale()
i setFemale()
metod, a zatem nie trwałby Person
wcale.
Cel jest inny:
Słowo transient
kluczowe i @Transient
adnotacja mają dwa różne cele: jeden dotyczy serializacji, a drugi uporczywości . Jako programiści często łączymy te dwie koncepcje w jedną, ale ogólnie nie jest to dokładne. Trwałość odnosi się do cechy państwa, która przeżywa proces, który go stworzył. Serializacja w Javie odnosi się do procesu kodowania / dekodowania stanu obiektu jako strumienia bajtów.
Słowo transient
kluczowe jest silniejszym warunkiem niż @Transient
:
Jeśli pole używa transient
słowa kluczowego, pole to nie będzie serializowane, gdy obiekt zostanie przekonwertowany na strumień bajtów. Ponadto, ponieważ JPA traktuje pola oznaczone transient
słowem kluczowym jako opatrzone @Transient
adnotacją, JPA również nie utrwali tego pola.
Z drugiej strony, pola z adnotacjami @Transient
same zostaną przekonwertowane na strumień bajtów, gdy obiekt zostanie zserializowany, ale JPA nie utrwali go. Dlatego transient
słowo kluczowe jest silniejszym warunkiem niż @Transient
adnotacja.
Przykład
To nasuwa pytanie: dlaczego ktokolwiek miałby chcieć serializować pole, które nie jest utrwalone w bazie danych aplikacji? Rzeczywistość jest taka, że serializacja służy nie tylko do wytrwałości . W aplikacji Enterprise Java musi istnieć mechanizm wymiany obiektów między rozproszonymi komponentami ; serializacja zapewnia wspólny protokół komunikacyjny do obsługi tego. Zatem pole może zawierać informacje krytyczne do celów komunikacji między komponentami; ale to samo pole może nie mieć żadnej wartości z perspektywy trwałości.
Załóżmy na przykład, że algorytm optymalizacji jest uruchomiony na serwerze i załóżmy, że ten algorytm zajmuje kilka godzin. Dla klienta ważne jest posiadanie najnowocześniejszego zestawu rozwiązań. Tak więc klient może subskrybować serwer i otrzymywać okresowe aktualizacje podczas fazy wykonywania algorytmu. Te aktualizacje są dostarczane za pomocą ProgressReport
obiektu:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
Solution
Klasa może wyglądać następująco:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Serwer utrzymuje każdy ProgressReport
z nich w swojej bazie danych. Serwer nie chce się utrzymywać estimatedMinutesRemaining
, ale klient z pewnością dba o te informacje. Dlatego estimatedMinutesRemaining
jest opatrzony adnotacją przy użyciu @Transient
. Gdy finał Solution
jest zlokalizowany przez algorytm, jest on utrwalany przez JPA bezpośrednio bez użycia ProgressReport
.
@Unpersisted
.
@Ephemeral
. Według Merriam Webster: Kiedy efemeria została po raz pierwszy wydrukowana w języku angielskim w 1600 roku, „był to termin naukowy stosowany do krótkotrwałych gorączek, a później do organizmów (takich jak owady i kwiaty) o bardzo krótkim okresie życia. Wkrótce potem , nabrał rozszerzonego sensu odnoszącego się do wszystkiego, co przelotne i krótkotrwałe (jak w „efemerycznych przyjemnościach”). ”
transient
pola za pośrednio @Transient
opatrzone adnotacją. Jeśli więc użyjesz transient
słowa kluczowego, aby zapobiec serializacji pola, to również nie trafi ono do bazy danych.
Jeśli chcesz tylko pola nie będzie się utrzymywał, zarówno przemijające i @Transient pracy. Ale pytanie brzmi: dlaczego @Transient, ponieważ transient już istnieje.
Ponieważ pole @Transient nadal będzie serializowane!
Załóżmy, że tworzysz encję, wykonując pewne obliczenia pochłaniające procesor, aby uzyskać wynik, a wynik ten nie zostanie zapisany w bazie danych. Ale chcesz wysłać encję do innych aplikacji Java do użycia przez JMS, wtedy powinieneś użyć @Transient
, a nie słowa kluczowego JavaSE transient
. Dzięki temu odbiorniki działające na innych maszynach wirtualnych mogą zaoszczędzić czas na ponowne obliczenia.
Spróbuję odpowiedzieć na pytanie „dlaczego”. Wyobraź sobie sytuację, w której masz ogromną bazę danych z dużą ilością kolumn w tabeli, a Twój projekt / system używa narzędzi do generowania jednostek z bazy danych. (Hibernacja ma takie, itp ...) Załóżmy teraz, że zgodnie z logiką biznesową potrzebujesz określonego pola, aby NIE można było go utrwalić. Musisz „skonfigurować” swój byt w określony sposób. Podczas gdy słowo kluczowe Transient działa na obiekcie - ponieważ zachowuje się w języku Java, @Transient służy wyłącznie do odpowiadania na zadania dotyczące tylko zadań związanych z trwałością.