JPA Transient Annotation и JSON
Это следующий вопрос по аннотации JPA Transient
Почему JPA имеет аннотацию @Transient?
У меня есть переходная переменная, которую я не хочу сохранять, и она отмечена кратковременной аннотацией.
Однако, когда я хочу создать JSON из моего контроллера останова, эта переходная переменная недоступна в выведенном JSON.
POJO PublicationVO прямолинейно без каких-либо причудливых атрибутов, только некоторые частные атрибуты (которые сохраняются) с геттерами и сеттерами и 1 переходная переменная.
@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;
}
Публикация VO выглядит следующим образом
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 + "]";
}
}
Когда я вижу инструкцию debug для публикацииVO в своих журналах, переходная переменная включается в вывод, но в моем клиентском коде переходная переменная не включена в ответ json.
Любая помощь очень ценится.
Спасибо,
Damien
Ответы
Ответ 1
Вопреки тому, что я говорил вам в комментариях, кажется, что Джексон действительно заботится о аннотациях JPA, когда они используются для сериализации экземпляров классов сущностей, благодаря модулю Jackson Hibernate.
В этом модуле есть HibernateAnnotationIntrospector, который в документации называется
простой AnnotationIntrospector, который добавляет поддержку использования Transient для обозначают игнорируемые поля (наряду с Джексоном и/или JAXB Аннотации).
И, как вы можете видеть здесь, поведение Джексона по умолчанию заключается в проверке любой аннотации @Transient
, которую он может найти.
Итак, в конце концов, ваша проблема может быть решена любым из этих трех способов:
- Настройте Джексона (используя метод HibernateAnnotationIntrospector setUseTransient), чтобы отключить проверку аннотаций
@Transient
(подробности реализации см. в этом ответе).
- Используйте другой объект, чем
PublicationVO
, как возвращаемый результат вашего метода getPublicationDetailsJSON
. Вам нужно будет скопировать свойства из вашего объекта значения в объект, возвращаемый в какой-то момент.
- Удалите аннотацию
@Transient
и сохраните свойство (но я бы понял, если это не вариант для вас, поскольку у вас, вероятно, есть веская причина сделать это свойство JPA-переходным в первую очередь).
ура
Ответ 2
Я просто добавил JsonSerialize и JsonDeserialize аннотации.
@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
Ответ 3
Просто добавлю ответ, предоставленный m4rtin
Я пошел с первым подходом - Configure Jackson (используя метод setUseTransient HibernateAnnotationIntrospector setUseTransient), чтобы отключить проверку аннотаций @Transient.
В моем проекте я должен был следовать следующему потоку, чтобы избежать сериализации джексона на непривлекательных ленивых объектах
Избегайте сериализации Джексона на непривлекательных ленивых объектах
Чтобы настроить мой проект, чтобы не игнорировать временные аннотации, я установил Hibernate4Module следующим образом
Hibernate4Module hm = new Hibernate4Module();
hm.disable(Feature.USE_TRANSIENT_ANNOTATION);
Спасибо за вашу помощь в этом m4rtin
Ответ 4
Я использую как @Transient, так и @JsonProperty, тогда он работает!
@Transient
@JsonProperty
private String mapImageSrc;
Ответ 5
Что это сработало для меня:
@Transient
@JsonProperty
в GETTER (не в определении частного поля)
И
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
аннотируя класс
Ответ 6
Так как никакое другое решение здесь не работало для меня, позвольте мне опубликовать мое решение, как он помогло:
@Transient
@JsonSerialize
private String mapImageSrc;
Это кажется лучшим решением для меня, поскольку аннотация для @JsonSerialize
была сделана для этого случая использования.
Ответ 7
У меня такая же проблема. Ниже решение сработало для меня:
@Bean
public Module hibernate5Module() {
Hibernate5Module hnetModule = new Hibernate5Module();
hnetModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
return hnetModule;
}
Благодаря m4rtin.
Ответ 8
Попробуйте @JsonView после добавления @Transient
Ответ 9
использовать @JsonIgnore в com.fasterxml.jackson.annotation
существует также переменная @JsonFormat for Date.
работает для меня
Ответ 10
В моем случае работает только с этим:
@Transient
@JsonGetter(value = "transientProperty")
public String getSomething() {
return something;
}
Я надеюсь, что это может быть полезно для кого-то.
С уважением.