This is a follow up to the following question on the JPA Transient annotation Why does JPA have a @Transient annotation?
I have a transient variable that I do not want to persist and it is marked with the transient annotation. However, when I want to produce JSON from my rest controller, this transient variable is not available in the outputted JSON.
The POJO PublicationVO is straight forward with no fancy attributes, just some private attributes (that are persisted) with getters and setters and 1 transient variable.
@RequestMapping(value = { "{publicationId}"}, method = RequestMethod.GET, produces = "application/json") @ResponseBody public PublicationVO getPublicationDetailsJSON(@PathVariable(value = "publicationId") Integer publicationId) { LOG.info("Entered getPublicationDetailsJSON - publicationId: " + publicationId); //Call method to get the publicationVO based on publicationId PublicationVO publicationVO = publicationServices.getPublicationByIdForRestCalls(publicationId); LOG.info("publicationVO:{}", publicationVO); LOG.info("Exiting getPublicationDetailsJSON"); return publicationVO; }
The PublicationVO is as follows
package com.trinity.domain.dao; import java.util.Calendar; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Transient; import com.fasterxml.jackson.annotation.JsonInclude; @Entity @Table(name = "publication") public class PublicationVO { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "publicationName", unique = false, nullable = false, length = 200) private String publicationName; @Column(name = "publicationSource", unique = false, nullable = false, length = 45) private String publicationSource; @Column(name = "dateAdded", unique = false, nullable = false) private Calendar dateAdded; @Transient private float percentageProcessed; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getPublicationName() { return publicationName; } public void setPublicationName(String publicationName) { this.publicationName = publicationName; } public String getPublicationSource() { return publicationSource; } public void setPublicationSource(String publicationSource) { this.publicationSource = publicationSource; } public Calendar getDateAdded() { return dateAdded; } public void setDateAdded(Calendar dateAdded) { this.dateAdded = dateAdded; } public float getPercentageProcessed() { return percentageProcessed; } public void setPercentageProcessed(float percentageProcessed) { this.percentageProcessed = percentageProcessed; } @Override public String toString() { return "PublicationVO [id=" + id + ", publicationName=" + publicationName + ", publicationSource=" + publicationSource + ", dateAdded=" + dateAdded + ", percentageProcessed=" + percentageProcessed + "]"; } }
When I see the debug statement for publicationVO in my logs, the transient variable is included in the output but in my client code, the transient variable is not included in the json response.
Any help is greatly appreciated.
Thank you, Damien
@Transient annotation in JPA or Hibernate is used to indicate that a field is not to be persisted or ignore fields to save in the database. @Transient exist in javax. persistence package. It is used to annotate a property or field of an entity class, mapped superclass, or embeddable class.
What is @Transient annotation in Spring? @Transient annotation is used to mark a field to be transient for the mapping framework, which means the field marked with @Transient is ignored by mapping framework and the field not mapped to any database column (in RDBMS) or Document property (in NOSQL).
To ignore a field, annotate it with @Transient so it will not be mapped by hibernate.
When persisting Java objects into database records using an Object-Relational Mapping (ORM) framework, we often want to ignore certain fields. If the framework is compliant with the Java Persistence API (JPA), we can add the @Transient annotation to these fields.
I simply added JsonSerialize and JsonDeserialize annotations.
@Transient @JsonSerialize @JsonDeserialize private String myField;
Contrary to what I was telling you in comments, it seems that Jackson does care about JPA annotations when used to serialize instances of entity classes thanks to the Jackson's Hibernate module.
Within that module, there is an HibernateAnnotationIntrospector that the documentation refers to as a
simple AnnotationIntrospector that adds support for using Transient to denote ignorable fields (alongside with Jackson and/or JAXB annotations).
And as you can see here, the default behavior of Jackson is to check for any @Transient
annotation it can find.
So in the end, your problem can be solved in either of those 3 ways :
@Transient
annotations (see this answer for implementation details).PublicationVO
as the returned result of your getPublicationDetailsJSON
method. You'll have to copy properties from your value object to the object being returned at some point.@Transient
annotation and persist the property (but I would understand if that is not an option for you since you probably have good reason to have made this property JPA-transient in the first place).Cheers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With