Ответы:
transient
Ключевое слово Java используется для обозначения того, что поле не должно быть сериализовано, тогда как @Transient
аннотация JPA используется для указания того, что поле не должно сохраняться в базе данных, т.е. их семантика различна.
Потому что они имеют разные значения. @Transient
Аннотаций сообщает поставщик JPA не сохраняются каким - либо (не- transient
) атрибута. Другой говорит платформе сериализации не сериализовать атрибут. Возможно, вы захотите иметь @Transient
свойство и все же его сериализовать.
Как уже говорили другие, @Transient
используется для пометки полей, которые не должны сохраняться. Рассмотрим этот короткий пример:
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);
}
}
Когда этот класс подается в JPA, он сохраняет gender
и id
не пытается сохранить вспомогательные логические методы - без @Transient
базовой системы будет жаловаться, что класс Entity Person
отсутствует setMale()
и setFemale()
методы и, следовательно, не будут сохраняться Person
вообще.
Цель другая:
transient
Ключевые слова и @Transient
аннотации имеют две разных целей: один сделку с сериализацией и один сделку с сохранением . Как программисты, мы часто объединяем эти два понятия в одно, но в целом это не совсем точно. Постоянство относится к характеристике государства, которое переживает процесс, который его создал. Сериализация в Java относится к процессу кодирования / декодирования состояния объекта как потока байтов.
transient
Ключевое слово является более сильным , чем условие @Transient
:
Если в поле используется transient
ключевое слово, это поле не будет сериализовано при преобразовании объекта в поток байтов. Кроме того, поскольку JPA рассматривает поля, помеченные transient
ключевым словом, как имеющие @Transient
аннотацию, JPA также не сохранит это поле.
С другой стороны, поля аннотированные @Transient
одни будут быть преобразованы в поток байтов при сериализации объекта, но это не будет сохраняться на JPA. Поэтому transient
ключевое слово является более строгим условием, чем @Transient
аннотация.
пример
Возникает вопрос: зачем кому-либо хотеть сериализовать поле, которое не сохраняется в базе данных приложения? Реальность такова, что сериализация используется не только для настойчивости . В приложении Enterprise Java должен быть механизм обмена объектами между распределенными компонентами ; Сериализация обеспечивает общий протокол связи, чтобы справиться с этим. Таким образом, поле может содержать критическую информацию для целей межкомпонентной связи; но это же поле может не иметь значения с точки зрения постоянства.
Например, предположим, что алгоритм оптимизации выполняется на сервере, и предположим, что этот алгоритм занимает несколько часов. Для клиента важно иметь самый современный набор решений. Таким образом, клиент может подписаться на сервер и получать периодические обновления на этапе выполнения алгоритма. Эти обновления предоставляются с использованием ProgressReport
объекта:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
Solution
Класс может выглядеть следующим образом :
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Сервер сохраняет каждый ProgressReport
в своей базе данных. Сервер не хочет сохраняться estimatedMinutesRemaining
, но клиент, безусловно, заботится об этой информации. Таким образом, estimatedMinutesRemaining
аннотируется с помощью @Transient
. Когда финал Solution
определяется алгоритмом, он сохраняется в JPA напрямую, без использования ProgressReport
.
@Unpersisted
.
@Ephemeral
. Согласно Merriam Webster: когда эфемерное впервые было напечатано на английском языке в 1600-х годах, «это был научный термин, применяемый к кратковременным лихорадкам, а затем к организмам (таким как насекомые и цветы) с очень короткими периодами жизни. Вскоре после этого оно приобрело расширенный смысл, относящийся ко всему мимолетному и недолговечному (как в «эфемерных удовольствиях») ».
transient
поля неявно имеющими @Transient
аннотацию. Поэтому, если вы используете transient
ключевое слово для предотвращения сериализации поля, оно также не попадет в базу данных.
Если вы просто хотите, чтобы поле не сохранялось, работают как переходные, так и @Transient . Но вопрос в том, почему @Transient, так как переходный процесс уже существует.
Потому что поле @Transient все равно будет сериализовано!
Предположим, вы создали сущность, выполнив некоторое потребление ресурсов процессора, чтобы получить результат, и этот результат не будет сохранен в базе данных. Но вы хотите отправить объект в другие приложения Java для использования JMS, тогда вам следует использовать @Transient
, а не ключевое слово JavaSE transient
. Таким образом, получатели, работающие на других виртуальных машинах, могут сэкономить свое время для повторного расчета.
Я постараюсь ответить на вопрос «почему». Представьте себе ситуацию, когда у вас есть огромная база данных с большим количеством столбцов в таблице, и ваш проект / система использует инструменты для создания сущностей из базы данных. (У Hibernate есть такие и т. Д.). Теперь предположим, что в соответствии с вашей бизнес-логикой вам нужно определенное поле, НЕ подлежащее сохранению. Вы должны «настроить» свою сущность определенным образом. В то время как ключевое слово Transient работает с объектом - так как оно ведет себя в языке Java, @Transient предназначен только для решения задач, относящихся только к задачам сохранения.