JPA 瞬态注释和 JSON [英] JPA Transient Annotation and JSON

查看:38
本文介绍了JPA 瞬态注释和 JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对 JPA Transient 注释的以下问题的跟进为什么JPA有@Transient注解?

This is a follow up to the following question on the JPA Transient annotation Why does JPA have a @Transient annotation?

我有一个不想保留的瞬态变量,它标有瞬态注释.但是,当我想从 rest 控制器生成 JSON 时,输出的 JSON 中没有此瞬态变量.

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 以及 1 个瞬态变量的私有属性(持久化).

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;
}

发布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 的调试语句时,transient 变量包含在输出中,但在我的客户端代码中,transient 变量不包含在json 响应中.

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.

非常感谢任何帮助.

谢谢,达米安

推荐答案

与我在评论中告诉你的相反,由于 Jackson 的 Hibernate 模块.

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.

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

Within that module, there is an HibernateAnnotationIntrospector that the documentation refers to as a

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

simple AnnotationIntrospector that adds support for using Transient to denote ignorable fields (alongside with Jackson and/or JAXB annotations).

正如你所看到的 这里,Jackson 的默认行为是检查它可以找到的任何@Transient 注释.

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 注释的检查(请参阅 此答案 了解实施详情).
  2. 使用除 PublicationVO 之外的另一个对象作为 getPublicationDetailsJSON 方法的返回结果.您必须将属性从值对象复制到某个时候返回的对象.
  3. 删除 @Transient 注释并保留该属性(但我会理解这是否不适合您,因为您可能有充分的理由首先将此属性设为 JPA-transient).
  1. Configure Jackson (using HibernateAnnotationIntrospector's setUseTransient method) to disable the check for @Transient annotations (see this answer for implementation details).
  2. Use another object than PublicationVO as the returned result of your getPublicationDetailsJSON method. You'll have to copy properties from your value object to the object being returned at some point.
  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).

干杯

这篇关于JPA 瞬态注释和 JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆