La anotación @Transient se utiliza para indicarle a JPA que un atributo de una Entidad no debe de ser persistente, de esta manera, JPA pasa por alto el atributo y no es tomado en cuenta a la hora de persistir el Objeto.
En la práctica no es común utilizar esta anotación, debido a que las Entidades por lo general solo tiene los atributos que mapean con la base de datos. Sin embargo, existen ocasiones en donde puede ser útil. Un ejemplo muy habitual es cuando agregamos un logger a la clase entidad. Esta instancia de java.util.logging.Logger será una propiedad más de la entidad, pero no deseamos que sea persistente, para lo cual lo marcamos con @Transient. Retomaremos la Entidad Employee que hemos utilizado en todo este tutorial para analizar cómo quedaría:
package com.obb.jpa.jpaturorial.entity; import java.util.Calendar; import java.util.Objects; import java.util.logging.Logger; import javax.persistence.*; /** * @author Oscar Blancarte */ @Entity @Table( name = "EMPLOYEES" , schema = "jpatutorial", indexes = {@Index(name = "name_index", columnList = "name",unique = true)} ) public class Employee { @Transient private static final Logger logger = Logger.getLogger(Employee.class.getSimpleName()); @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "EmployeeTable") @Column(name = "ID") private Long id; @Column(name = "NAME", nullable = false, length = 150) private String name; @Column(name = "SALARY", nullable = false, scale = 2) private double salary; @Column(name = "REGIST_DATE", updatable = false, nullable = false) @Temporal(TemporalType.DATE) private Calendar registDate; @Column(name="STATUS", nullable = false, length = 8 ) @Enumerated(value = EnumType.STRING) private Status status; @Column(name = "PHOTO" ,nullable = true) @Basic(optional = false, fetch = FetchType.EAGER) @Lob() private byte[] photo; /** * GETs and SETs */ }
Como vemos en la entidad Employee, marcamos la propiedad logger como @Transiente, de esta manera, este atributo será ignorado por JPA. Si ejecutamos el programa veremos que no se creara una columna para esta propiedad.
Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, https://codmind.com/courses/jpa
La anotación @Transient no tiene atributos, por lo que con solo agregarla JPA sabrá que debe ignorar el campo.
NOTA: Este artículo es solo una sección del Tutorial de JPA, para ver el contenido completo de este tutorial regresa al Índice en el botón de abajo.
Hola Oscar, primero reconocerle el gran trabajo que estas haciendo en este blog.
Un compañero me ha hecho una pregunta a raíz de leer su tutorial de JPA. Quería hacer una pregunata:
¿Cual crees que es el comportamiento a la hora de hacer un persist, merge si la entidad tiene atributos que no son @Transient pero tampoco están mapeados a una columna?
Saludos
Gracias por el comentario y que bueno que el material aquí expuesto es de tu agrado 🙂
Con respecto a tu pregunta. JPA mapeara de forma automática todo los campos no anotados (@), sin embargo, el mapeo dependerá del tipo de datos, por ejemplo, lo datos primitivos o clases wraper será automaticamente mepeadas como una columna a la misma tabla de la Entidad y el tipo de datos de la columna dependerá del tipo de dato la propiedad, por ejemplo VARCHAR para los Strings, Numbers para los Integer, Floats y Dubles y TIMESTAMP para los Data y Calendar, (el nombre de la columna será el mismo que la propiedad). Por otra parte, si la propiedad es de tipo de otra Entidad, entonces asumirá una relación ManyToOne y si la propiedad es una Colección (Collection) creará una relación OneToMany.
Ahora bien, el comportamiento puede variar ligeramente según la implementación de JPA, por lo que nunca se recomienda asumir el comportamiento y definir siempre todas las anotaciones necesarias para garantizar el correcto funcionamiento sin importar la implementación de JPA.
Hola Óscar. Muchas gracias por las aportaciones, me parecen de muchísima ayuda. A raíz de esto, me he topado con un problema que no sé si es posible resolver con anotaciones (si la hay la desconozco). Quisiera ignorar una propiedad tipo entidad sólo si viene nula (en el caso de que venga nula, ahora mismo da un fallo de persistencia). Con la anotación @Transient la ignora siempre, sea nula o no.
Muchas gracias de antemano.
hola María, lo que quieres hacer no es posible, ya que la tomas en cuenta para la persistencia o no, sin embargo, toma en cuenta que si la entidad viene nula se insertar como Null en la columna, no deberías de tener problemas con eso, a menos que me cuentes cual es el problema y que es lo que buscas resolver.
saludos
Hola Oscar, gracias por tan excelente artículo. Yo tengo el mismo problema, necesito si o si guardar una propiedad anotada con @transient pero aún no descubro cómo, o si esto será posible sin modificaciones en la entidad.
Desde ya muchas gracias, saludos desde Argentina
Hola Melina, ese es el problema, una propiedad @Transient no se guarda en la base de datos
Hola Oscar,
Espero que tu me puedas ayudar. Resulta que tengo una entidad con una serie de campos, y uno de ellos marcado como @Transient audDescription. Ademas he definido un AuditListener en el que cuando la entidad principal se actualice, se ejecute el evento PostUpdate. El evento se me esta ejecutando perfectamente mi problema viene es que esa propiedad viene a nulo cuando ejecuto un Update o Delete sin embargo cuando hago un insert (save) me va bien. Tanto el update como el delete (borrado logico), utilizo el metodo save.
¿Puedes intuir porque me esta llegando esa variable a nulo en los Update sin embargo al hacer insert me viene relleno.?
Gracias y un saludo.
Primero que nada, me imagino que sabes que @Transient le indica a JPA que ese valor no se guarde en la base de datos, por lo tanto, lo más seguro es que cuando crear la entidad le estableces un valor, pero una vez que la cargas de la base de datos, ese propiedad se quedan en Null, por lo tanto, lo más seguro es que cuando actualizas o borras, esa propiedad esta Null.