Подтвердить что ты не робот

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

4b9b3361

Ответ 1

Вопреки тому, что я говорил вам в комментариях, кажется, что Джексон действительно заботится о аннотациях JPA, когда они используются для сериализации экземпляров классов сущностей, благодаря модулю Jackson Hibernate.

В этом модуле есть HibernateAnnotationIntrospector, который в документации называется

простой AnnotationIntrospector, который добавляет поддержку использования Transient для обозначают игнорируемые поля (наряду с Джексоном и/или JAXB Аннотации).

И, как вы можете видеть здесь, поведение Джексона по умолчанию заключается в проверке любой аннотации @Transient, которую он может найти.

Итак, в конце концов, ваша проблема может быть решена любым из этих трех способов:

  1. Настройте Джексона (используя метод HibernateAnnotationIntrospector setUseTransient), чтобы отключить проверку аннотаций @Transient (подробности реализации см. в этом ответе).
  2. Используйте другой объект, чем PublicationVO, как возвращаемый результат вашего метода getPublicationDetailsJSON. Вам нужно будет скопировать свойства из вашего объекта значения в объект, возвращаемый в какой-то момент.
  3. Удалите аннотацию @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;
}

Я надеюсь, что это может быть полезно для кого-то. С уважением.