Ceci fait suite à la question suivante sur l'annotation transitoire JPA Pourquoi JPA a-t-elle une annotation @Transient?
J'ai une variable transitoire que je ne veux pas persister et elle est marquée avec l'annotation transitoire. Cependant, lorsque je veux produire du JSON à partir de mon contrôleur de repos, cette variable transitoire n'est pas disponible dans le JSON généré.
Le POJO PublicationVO est simple, sans attribut de fantaisie, juste quelques attributs privés (qui sont persistants) avec des getters et setters et 1 variable transitoire.
@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;
}
La PublicationVO est la suivante
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 + "]";
}
}
Lorsque je vois l'instruction de débogage pour publicationVO dans mes journaux, la variable transitoire est incluse dans la sortie mais dans mon code client, la variable transitoire n'est pas incluse dans la réponse json.
Toute aide est grandement appréciée.
Merci, Damien
Contrairement à ce que je vous disais dans les commentaires, il semble que Jackson se soucie des annotations JPA lorsqu'il est utilisé pour sérialiser des instances de classes d'entités grâce au module Hibernate de Jackson .
Dans ce module, il y a un HibernateAnnotationIntrospector que la documentation appelle un
annotationIntrospector simple qui ajoute la prise en charge de l'utilisation de Transient pour désigner les champs ignorables (avec les annotations Jackson et/ou JAXB).
Et comme vous pouvez le voir ici , le comportement par défaut de Jackson est de vérifier tout @Transient
annotation qu'il peut trouver.
Donc, à la fin, votre problème peut être résolu de l'une des trois façons suivantes:
@Transient
annotations (voir cette réponse pour les détails d'implémentation).PublicationVO
comme résultat renvoyé de votre méthode getPublicationDetailsJSON
. Vous devrez copier les propriétés de votre objet de valeur vers l'objet renvoyé à un moment donné.@Transient
annoter et conserver la propriété (mais je comprendrais si ce n'est pas une option pour vous car vous avez probablement de bonnes raisons d'avoir rendu cette propriété transitoire JPA en premier lieu).À votre santé
J'ai simplement ajouté JsonSerialize et JsonDeserialize annotations.
@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
Juste pour ajouter à la réponse fournie par m4rtin
Je suis allé avec la première approche - Configurer Jackson (en utilisant la méthode setUseTransient de HibernateAnnotationIntrospector) pour désactiver la vérification des annotations @Transient.
Dans mon projet, j'ai suivi devait suivre le fil suivant pour éviter la sérialisation jackson sur les objets paresseux non récupérés Évitez la sérialisation Jackson sur les objets paresseux non récupérés
Pour configurer mon projet pour ne pas ignorer les annotations transitoires, j'ai configuré le Hibernate4Module comme suit
Hibernate4Module hm = new Hibernate4Module();
hm.disable(Feature.USE_TRANSIENT_ANNOTATION);
Merci pour votre aide sur ce m4rtin
J'utilise à la fois @Transient et @JsonProperty, alors ça marche!
@Transient
@JsonProperty
private String mapImageSrc;
Ce que cela a fonctionné pour moi:
@Transient
@JsonProperty
dans le GETTER (pas dans la définition du champ privé)
ET
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
annoter la classe
Puisqu'aucune autre solution ici n'a fonctionné pour moi, permettez-moi de poster ma solution comment elle a fait l'affaire pour moi:
@Transient
@JsonSerialize
private String mapImageSrc;
Cela semble être la meilleure solution pour moi car le @JsonSerialize
une annotation a été faite pour ce cas d'utilisation.
J'ai eu le même problème. La solution ci-dessous a fonctionné pour moi:
@Bean
public Module hibernate5Module() {
Hibernate5Module hnetModule = new Hibernate5Module();
hnetModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
return hnetModule;
}
Merci à m4rtin.
Essayez @JsonView après avoir ajouté @Transient
utilisez @JsonIgnore dans com.fasterxml.jackson.annotation, il existe également @JsonFormat pour la variable Date. travaille pour moi