当前位置: 首页 > 知识库问答 >
问题:

JPA瞬态注释和JSON

魏英勋
2023-03-14

这是关于JPA瞬态注释的以下问题的后续问题,为什么JPA有@Transient注释?

我有一个我不想保留的瞬态变量,它被标记为瞬态注释。但是,当我想从我的rest控制器生成JSON时,这个瞬态变量在输出的JSON中不可用。

POJO PublicationVO是直截了当的,没有奇特的属性,只有一些私有属性(持久化的),带有getter和setter以及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 + "]";
    }
}

当我在日志中看到publicationVO的调试语句时,瞬态变量包含在输出中,但在客户端代码中,瞬态变量不包含在json响应中。

非常感谢您的帮助。

谢谢你戴米恩

共有3个答案

常光明
2023-03-14

只是为了进一步补充m4rtin提供的答案

我使用了第一种方法——配置Jackson(使用HibernateanNotationIntropector的SetUseTransive方法)来禁用对@Transient注释的检查。

在我的项目中,我必须遵循以下线程以避免杰克逊对非获取的懒惰对象进行序列化避免杰克逊对非获取的懒惰对象进行序列化

为了将我的项目配置为不忽略瞬态注释,我设置了Hibernate4Module,如下所示

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

谢谢你在这件事上的帮助

单于帅
2023-03-14

与我在评论中告诉你的相反,由于Jackson的Hibernate模块,当用于序列化实体类实例时,Jackson似乎确实关心JPA注释。

在该模块中,有一个HibernateAnnotationIntrospector,文档将其称为

简单的AnnotationIntrospector,增加了对使用Transient表示可忽略字段的支持(以及Jackson和/或JAXB注释)。

正如您在这里看到的,Jackson的默认行为是检查它可以找到的任何瞬态注释。

所以最后,你的问题可以用这三种方法中的任何一种来解决:

  1. 配置Jackson(使用HibernateAnnotationIntrospector的setusetransive方法)以禁用对瞬态注释的检查(有关实现细节,请参阅此答案)
  2. 使用除PublicationVO之外的另一个对象作为您的getPublicationDetailsJSON方法的返回结果。您必须将属性从值对象复制到某个时刻返回的对象
  3. 删除Transient注释并持久化该属性(但如果您没有选择,我会理解,因为您可能有充分的理由首先将该属性设置为JPA Transient)

干杯干杯

任昊阳
2023-03-14

我只是添加了JsonSerialize和JsonDeserialize注释。

@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
 类似资料:
  • 问题内容: 这是有关JPA Transient批注的以下问题的后续解答 为什么JPA具有@Transient批注? 我有一个我不想保留的瞬态变量,并用瞬态注释标记。但是,当我想从我的rest控制器生成JSON时,此瞬态变量在输出的JSON中不可用。 POJO PublicationVO直截了当,没有花哨的属性,只有一些具有getter和setter和1个瞬态变量的私有属性(已保留)。 The Pu

  • 问题内容: 我想避免序列化(在JMS / AMF中),但仍使用JPA / Hibernate保留该字段。 是修改我的朋友?注释和修饰符是否相关? Java规范明确指出,系统服务不会将瞬态字段保存到持久性存储中。但是hibernate是系统服务吗?(我不这样认为) http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.h

  • 问题内容: 有一个结构。我想以这种方式链接这三个实体:公司应包含ID,公司名称和部门列表,每个部门都有一个工人列表,ID和部门名称。每个工人都有名字,身份证。 我试图与一对多和多对一建立联系,但未成功。 公司 部 工人 我从开始: 它填充公司,但不填充其他表,也没有创建任何联接(映射)错误: 问题答案: 除了Glenn Lane的答案中提到的级联,您还需要了解双向关联是如何工作的。 它们有一个所有

  • 问题内容: 有一个结构。我想以这种方式链接这三个实体:公司应包含ID,公司名称和部门列表,每个部门都有一个工人列表,ID和部门名称。每个工人都有名字,身份证。 我试图与一对多和多对一建立联系,但未成功。 公司 部门 工人 我从开始: 它填充公司,但不填充其他表,也没有创建任何联接(映射)错误: 问题答案: 除了Glenn Lane的答案中提到的级联,您还需要了解双向关联是如何工作的。 它们有一个所

  • 我有这个实体: 读取字段位于另一个表中,因此我将其设置为瞬态,以防止JPA映射错误。为了检索实体的内容,我想使用如下所示的本机查询: 问题是,我不知道如何将本机查询映射到实体。特别是,我不知道EntityManager是否会忽略@Transient字段。请帮忙。

  • 关于注释和注释,我遇到了一个有趣的问题在Spring Boot项目上,spring data jpa也在项目中。 基本上,我有软删除机制,这是为实体设置一个有效的日期(例如属性列在实体类中带有属性)。这些实体用注释类似于。这样,将设置为now和before的软删除的实体自动删除。(例如实体类) 我还有一些其他实体没有(例如实体类) 以及其他一些可用的表。如果是Jpa查询带注释的方法。我正面临着一些