Pourquoi est-ce que JPA a une annotation @Transient?
6 réponses
le mot clé transient
de Java est utilisé pour indiquer qu'un champ ne doit pas être sérialisé, tandis que L'annotation @Transient
de JPA est utilisée pour indiquer qu'un champ ne doit pas être persisté dans la base de données, c.-à-d. que leurs sémantiques sont différentes.
parce qu'ils ont des significations différentes. L'annotation @Transient
indique au fournisseur JPA de ne pas persister d'attribut (non - transient
). L'autre indique au cadre de sérialisation de ne pas sérialiser un attribut. Vous pourriez vouloir avoir une propriété @Transient
et la sérialiser encore.
comme d'autres l'ont dit, @Transient
est utilisé pour marquer des champs qui ne devraient pas être persisté. Prenons cet exemple:
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);
}
}
quand cette classe est alimentée à la JPA, il persiste le gender
et id
mais ne cherche pas à persister les méthodes booléennes helper-sans @Transient
le système sous-jacent se plaindrait que la classe D'entité Person
est manquante setMale()
et setFemale()
méthodes et donc ne persisterait pas Person
à tous.
objet différent:
le transient
mot-clé et @Transient
annotation ont deux buts différents: l'un traite de sérialisation et l'autre traite de persistance . En tant que programmeurs, nous combinons souvent ces deux concepts en un seul, mais ce n'est pas exact en général. persistance renvoie à la caractéristique de l'état qui survit au processus qui l'a créé. Sérialisation dans Java se réfère au processus de codage/décodage de l'état d'un objet comme un flux d'octets.
le mot-clé transient
est une condition plus forte que @Transient
:
si un champ utilise le mot-clé transient
, ce champ ne sera pas sérialisé lorsque l'objet est converti en flux octet. De plus, étant donné que JPA traite les champs marqués du transient
mot-clé comme ayant l'annotation @Transient
, le champ ne sera pas non plus persisté par JPA.
d'autre part, les champs annotés @Transient
seuls seront convertis en un flux d'octets lorsque l'objet est sérialisé, mais il ne sera pas persisté par JPA. Par conséquent, le mot-clé transient
est une condition plus forte que l'annotation @Transient
.
exemple
cela soulève la question: Pourquoi quelqu'un voudrait sérialiser un champ qui n'est pas persisté dans la base de données de l'application? La réalité est que la sérialisation est utilisée pour plus que la seule persistance . Dans une application Java D'entreprise il doit y avoir un mécanisme d'échange d'objets entre les composants distribués ; la sérialisation fournit un protocole de communication commun pour gérer cela. Ainsi, un champ peut contenir des informations critiques pour le but de la communication entre les composantes; mais ce même domaine peut ne pas avoir de valeur du point de vue de la persistance.
Par exemple, supposons qu'un algorithme d'optimisation est exécuté sur un serveur, et supposons que cet algorithme prend plusieurs heures. Pour un client, il est important d'avoir l'ensemble de solutions le plus à jour possible. Ainsi, un client peut s'abonner au serveur et recevoir des mises à jour périodiques pendant la phase d'exécution de l'algorithme. Ces mises à jour sont fournies à l'aide de la ProgressReport
objet:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
la classe Solution
pourrait ressembler à ceci:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
le serveur persiste chaque ProgressReport
à sa base de données. Le serveur ne se soucie pas de persister estimatedMinutesRemaining
, mais le client se soucie certainement de cette information. Par conséquent, le estimatedMinutesRemaining
est annoté en utilisant @Transient
. Lorsque le Solution
final est localisé par l'algorithme, il est persisté par JPA directement sans utiliser un ProgressReport
.
si vous voulez juste un champ ne sera pas persisté, à la fois transitoire et @transitoire travail. Mais la question Est de savoir pourquoi @Transient depuis transient existe déjà.
parce que @Transient field va encore être sérialisé!
supposons que vous créez une entité, en faisant un calcul de consommation de CPU pour obtenir un résultat et ceci résultat ne sera pas sauvegarder dans la base de données. Mais vous voulez envoyer l'entité à d'autres applications Java à utiliser par JMS, alors vous devez utiliser @Transient
, pas le mot-clé JavaSE transient
. Ainsi, les récepteurs fonctionnant sur D'autres VM peuvent économiser leur temps pour recalculer à nouveau.
je vais essayer de répondre à la question du "pourquoi". Imaginez une situation où vous avez une base de données énorme avec beaucoup de colonnes dans une table, et votre projet/système utilise des outils pour générer des entités à partir de la base de données. (Hibernation a ceux, etc...) Maintenant, supposons que par votre logique d'affaires vous avez besoin d'un domaine particulier pour ne pas être persisté. Vous devez "configurer" votre entité d'une manière particulière. Tandis que le mot-clé transitoire fonctionne sur un objet - comme il se comporte dans un langage java, le @transitoire seulement conçu pour répondre aux tâches qui se rapportent uniquement aux tâches de persistance.