Pourquoi est-ce que JPA a une annotation @Transient?

Java a le mot-clé transient . Pourquoi est-ce que JPA a @Transient au lieu de simplement utiliser le mot clé java déjà existant?

228
demandé sur deamon 2010-01-28 16:00:20

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.

353
répondu Jawher 2015-12-16 12:33:01

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.

99
répondu Pascal Thivent 2010-10-20 17:03:36

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.

80
répondu Esko 2010-06-13 09:10:02

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 .

34
répondu Austin D 2016-02-26 01:55:26

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.

15
répondu Sheng.W 2015-12-16 12:35:07

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.

0
répondu Dima R. 2015-12-16 19:36:37