Ответы:
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 предназначен только для решения задач, относящихся только к задачам сохранения.