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.

POJO PublicationVO是直截了当的,没有特别的属性,只有一些私有属性(持久化的),带有getter和setter以及一个临时变量.

@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.

谢谢, 达米恩

推荐答案

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

简单的AnnotationIntrospector,增加了对使用Transient to的支持

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 :

  1. 配置Jackson(使用HibernateAnnotationIntrospector的setUseTransient方法)禁用@Transient个注释的判断(有关实现细节,请参见this answer).
  2. 使用PublicationVO以外的另一个对象作为getPublicationDetailsJSON方法的返回结果.您必须将属性从值对象复制到某个时刻返回的对象.
  3. Remove the @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).

干杯

Json相关问答推荐

JOLT将扁平数组内其他字段的两个值相乘

JOLT拉平数组

我如何知道TJSONNumber是double还是double?

如何在VegaLite中应用Times New Roman,CaliBiri字体

解析JSON说函数parse_json不存在?

Ansible - 将文件内容添加到字典中

PostgreSQL:删除 JSONB 数组中每个元素的特定键

NiFi 使用嵌套数组将 avro 转换为 JSON 数组格式

父键中的 Perl JSON 数组

添加到数组时出错:找不到Add的重载和参数计数:1

如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?

没有很多类的 GSON 解析

Python Flask-Restful POST 不采用 JSON 参数

Django - 异常处理最佳实践和发送自定义错误消息

ASP.NET MVC:使用 JsonResult 控制属性名称的序列化

使用 jq,将对象数组转换为具有命名键的对象

在 JSON 编码的 HTML5 数据属性中转义/编码单引号

如何在不消除对象歧义的情况下使用 circe 解码 ADT

gson:将 null 视为空字符串

可以在 SharedPreferences 中保存 JSON 数组吗?