What is the (real) utility of the javax.persistence.Transient annotation?

3

The @Transient annotation serves to inform JPA that that attribute is not mapped to the table and / or should not be persisted.

In addition, after the entity that has annotated attributes with @Transient is persisted, these attributes return with their default values (except for the primitive types, they return with null and this can easily cause NullPointerException ).

The question is: why annotate an attribute with @Transient ?

  • If the attribute does not belong to the table or should not be persisted, should it not be removed from the entity?

  • Some say that attributes annotated with this annotation are useful for "loading calculated values", but in that case, would not a method be better than an attribute? Or better: if, again, this calculated value does not belong to the table, should it not be removed from the entity and acquired / redeemed otherwise?

asked by anonymous 09.11.2017 / 16:36

1 answer

1

As you mentioned, it serves to exclude a certain value from the JPA mapping and is useful for calculated attributes.

To give an example of where this is useful, imagine that this value is somewhat costly to obtain. As examples of these cases, I can cite this:

  • A value containing a total that has to be computed by accessing multiple entities scattered across multiple tables.

  • The contents of a file read from the disk.

  • Some data that belongs to the entity but that is not in the database, being obtained through a webservice.

Note that in all these cases, if you force the getter to have to recalculate this at all, performance will be poor. This could lead to multiple queries to multiple tables in the database, multiple readings of a file, or multiple queries to some webservice.

Doing these things in the getter is not a good idea, it's best if these things are all computed in the business logic rendering of the functionality in question, and the getter only returns the result, even more that a few people expect a getter to be a method with a high complexity (even because this is not usually a good programming practice).

The Java language already has a transient f modifier to do this in fields, but it can not be used for methods if you are doing mapping in getters instead of doing it in attributes. That's why they invented the @Transient annotation. In fact, the certain thing would be that the transient modifier did not exist and its behavior was replaced by a note, but at the time it was designed, there were no annotations in Java yet.

As for the question of placing this in the entity rather than in some other class, it is because the entity represents a concept of its domain with its respective business rules. It happens that these features that have to be computed are part of the business rule of the modeled entity, and therefore, there should be, otherwise it would possibly be a violation of the encapsulation.

The error (very common by the way) is to believe in the premise that the entity must reflect the database directly and imitate its structure, but this is not always true. Sometimes the entity format is not exactly the same as the database.

And even if the entity format faithfully reflects database modeling, add Venda to a totalVenda attribute that has the value resulting from the sum of the values of all items in the should be something to disrupt the JPA mapping.

    
09.11.2017 / 17:24