JPA Transient Annotation and JSON

2019-01-11 03:09发布

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

9条回答
smile是对你的礼貌
2楼-- · 2019-01-11 03:27

I simply added JsonSerialize and JsonDeserialize annotations.

@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
查看更多
forever°为你锁心
3楼-- · 2019-01-11 03:27

use @JsonIgnore in com.fasterxml.jackson.annotation there also is @JsonFormat for Date variable. works for me

查看更多
祖国的老花朵
4楼-- · 2019-01-11 03:29

I had the same problem. Below solution worked for me:

@Bean
public Module hibernate5Module() {
    Hibernate5Module hnetModule = new Hibernate5Module();
    hnetModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
    return hnetModule;
}

Thanks to m4rtin.

查看更多
孤傲高冷的网名
5楼-- · 2019-01-11 03:32

Try @JsonView after adding @Transient

查看更多
6楼-- · 2019-01-11 03:34

I use both @Transient and @JsonProperty, then it works!

@Transient
@JsonProperty
private String mapImageSrc;
查看更多
来,给爷笑一个
7楼-- · 2019-01-11 03:36

Just to add further to the answer provided by m4rtin

I went with the first approach - Configure Jackson (using HibernateAnnotationIntrospector's setUseTransient method) to disable the check for @Transient annotations.

In my project I follwed had to follow the following thread to avoid jackson serialization on non fetched lazy objects Avoid Jackson serialization on non fetched lazy objects

To configure my project to not ignore transient annotations, I set up the Hibernate4Module as follows

        Hibernate4Module hm = new Hibernate4Module();
    hm.disable(Feature.USE_TRANSIENT_ANNOTATION);

Thanks for your help on this m4rtin

查看更多
登录 后发表回答