Java имеет ключевое слово transient. Почему JPA имеет @Transient вместо простого использования уже существующего ключевого слова java?
Почему JPA имеет аннотацию @Transient?
Ответ 1
Ключевое слово Java transient используется для обозначения того, что поле не должно быть сериализовано, тогда как аннотация JPA @Transient используется, чтобы указать, что поле не сохраняется в базе данных, т.е. их семантика отличается.
Ответ 2
Потому что они имеют разные значения. Аннотация @Transient сообщает провайдеру JPA не сохранять какой-либо (не transient) атрибут. Другой говорит, что структура сериализации не сериализует атрибут. Возможно, вы захотите иметь свойство @Transient и все еще сериализовать его.
Ответ 3
Как говорили другие, @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 вообще.
Ответ 4
Назначение другое:
Ключевое слово transient и аннотация @Transient имеют две разные цели: речь идет о сериализации, а речь идет о сохранении. Как программисты, мы часто вступаем в брак с этими двумя концепциями в один, но это не совсем точно. Persistence относится к характеристике состояния, которое переживает процесс, который его создал. Сериализация в 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.
Ответ 5
Если вы хотите, чтобы поле не сохранялось, работают переходный и @Transient. Но возникает вопрос, почему @Transient, поскольку переходный уже существует.
Поскольку поле @Transient по-прежнему будет сериализовано!
Предположим, что вы создаете сущность, выполняя вычисления с использованием процессора, чтобы получить результат, и этот результат не будет сохранен в базе данных. Но вы хотите отправить объект другим приложениям Java для использования JMS, тогда вы должны использовать @Transient, а не ключевое слово JavaSE transient. Таким образом, приемники, работающие на других виртуальных машинах, могут сэкономить свое время, чтобы снова рассчитать.
Ответ 6
Я постараюсь ответить на вопрос "почему". Представьте себе ситуацию, когда у вас есть огромная база данных с большим количеством столбцов в таблице, а ваш проект/система использует инструменты для генерации сущностей из базы данных. (Hibernate имеет те и т.д.) Теперь предположим, что по вашей бизнес-логике вам понадобится конкретное поле, которое НЕ должно быть сохранено. Вы должны "настроить" свою сущность определенным образом. Хотя ключевое слово Transient работает на объекте - так как оно ведет себя в Java-языке, @Transient предназначен только для ответа на задачи, которые относятся только к задачам сохранения.