web-dev-qa-db-fra.com

Pourquoi JPA a-t-il une annotation @Transient?

Java a le transientkeyword. Pourquoi JPA utilise-t-il @Transient au lieu d'utiliser simplement le mot clé Java déjà existant?

259
deamon

Le mot-clé transient de Java indique qu'un champ ne doit pas être sérialisé, alors que l'annotation JPA @Transient sert à indiquer qu'un champ ne doit pas être conservé dans la base de données, c'est-à-dire que leur sémantique est différente.

405
Jawher

Parce qu'ils ont des significations différentes. L'annotation @Transient indique au fournisseur JPA de ne pas conserver d'attribut (non -transient). L'autre indique au framework de sérialisation de ne pas sérialiser un attribut. Vous voudrez peut-être avoir une propriété @Transient et tout en le sérialisant.

108
Pascal Thivent

Comme d'autres l'ont déjà dit, @Transient est utilisé pour marquer les champs qui ne doivent pas être persistés. Considérez ce court 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);
    }
}

Lorsque cette classe est transmise à l'APP, elle conserve les méthodes gender et id, mais n'essaie pas de conserver les méthodes booléennes d'assistance - sans @Transient, le système sous-jacent se plaint que la classe Entity Person manque les méthodes setMale() et setFemale() et ne persistera donc pas Person du tout.

89
Esko

Le but est différent:

Les mots-clés transient et @Transient ont deux objectifs différents: l’un traite de la sérialisation et l’autre de persistance . En tant que programmeurs, nous marions souvent ces deux concepts en un, mais ce n’est pas exact en général. Persistence fait référence à la caractéristique d'état qui survit au processus qui l'a créé. Sérialisation dans Java fait référence au processus de codage/décodage de l'état d'un objet sous forme de 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é lors de la conversion de l'objet en flux d'octets. De plus, étant donné que JPA considère que les champs marqués du mot clé transient ont l'annotation @Transient, le champ ne sera pas non plus conservé par JPA.

D'autre part, les champs annotés @Transient seul seront convertis en un flux d'octets lorsque l'objet est sérialisé, mais il ne sera pas conservé. par JPA. Par conséquent, le mot clé transient est une condition plus forte que l'annotation @Transient.

Exemple

Cela soulève la question suivante: pourquoi quelqu'un voudrait-il sérialiser un champ qui n'est pas conservé dans la base de données de l'application? La réalité est que la sérialisation est utilisée pour plus que la persistance . Dans une application d'entreprise Java, il doit exister un mécanisme permettant d'échanger des objets entre des composants distribués ; la sérialisation fournit un protocole de communication commun pour gérer cela. Ainsi, un champ peut contenir des informations critiques à des fins de communication inter-composants; mais ce même champ peut n'avoir aucune 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 prenne plusieurs heures. Pour un client, il est important de disposer des solutions les plus récentes. 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 l'objet ProgressReport:

@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 conserve chaque ProgressReport dans 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, la estimatedMinutesRemaining est annotée avec @Transient. Lorsque l'algorithme final Solution est localisé, il est persisté directement par JPA sans utiliser un ProgressReport.

44
Austin D

Si vous voulez juste qu'un champ ne soit pas persistant, les deux transitoire et @ Transient fonctionnent. Mais la question est de savoir pourquoi @ Transient puisque transitoire existe déjà.

Parce que le champ @Transient sera toujours sérialisé!

Supposons que vous créiez une entité en effectuant des calculs gourmands en ressources processeur pour obtenir un résultat, qui ne sera pas enregistré dans la base de données. Toutefois, si vous souhaitez envoyer l'entité à d'autres applications Java à utiliser par JMS, vous devez utiliser @Transient et non le mot clé JavaSE transient. Ainsi, les destinataires s'exécutant sur d'autres ordinateurs virtuels peuvent gagner du temps et effectuer un nouveau calcul.

17
Sheng.W

Je vais essayer de répondre à la question "pourquoi". Imaginez une situation où vous avez une énorme base de données avec beaucoup de colonnes dans une table, et votre projet/système utilise des outils pour générer des entités à partir d'une base de données. (Hibernate en a, etc ...) Supposons maintenant que, selon votre logique métier, vous avez besoin qu'un champ particulier NE soit PAS conservé. Vous devez "configurer" votre entité d'une manière particulière. Bien que le mot clé Transient fonctionne sur un objet - comme il se comporte dans un langage Java, le @Transient est uniquement conçu pour répondre aux tâches qui ne concernent que les tâches de persistance.

0
Dima R.