Java JPA 瞬态注释和 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25713884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA Transient Annotation and JSON
提问by Damien Gallagher
This is a follow up to the following question on the JPA Transient annotation Why does JPA have a @Transient annotation?
这是对 JPA Transient annotation 的以下问题的跟进 为什么 JPA 有 @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.
我有一个不想保留的瞬态变量,它标有瞬态注释。但是,当我想从我的 rest 控制器生成 JSON 时,这个瞬态变量在输出的 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.
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;
}
The PublicationVO is as follows
刊物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.Hymanson.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.
当我在日志中看到publicationVO 的调试语句时,transient 变量包含在输出中,但在我的客户端代码中,transient 变量未包含在json 响应中。
Any help is greatly appreciated.
任何帮助是极大的赞赏。
Thank you, Damien
谢谢你,达米安
采纳答案by m4rtin
Contrary to what I was telling you in comments, it seems that Hymanson does care about JPA annotations when used to serialize instances of entity classes thanks to the Hymanson's Hibernate module.
与我在评论中告诉你的相反,由于Hymanson 的 Hibernate 模块,当用于序列化实体类的实例时,Hymanson 似乎确实关心 JPA 注释。
Within that module, there is an HibernateAnnotationIntrospectorthat the documentation refers to as a
在该模块中,有一个HibernateAnnotationIntrospector,文档将其称为
simple AnnotationIntrospector that adds support for using Transient to denote ignorable fields (alongside with Hymanson and/or JAXB annotations).
简单的 AnnotationIntrospector,增加了对使用 Transient 表示可忽略字段的支持(以及 Hymanson 和/或 JAXB 注释)。
And as you can see here, the default behavior of Hymanson is to check for any @Transient
annotation it can find.
正如您在此处看到的,Hymanson 的默认行为是检查@Transient
它可以找到的任何注释。
So in the end, your problem can be solved in either of those 3 ways :
所以最后,您的问题可以通过以下三种方式之一解决:
- Configure Hymanson (using HibernateAnnotationIntrospector's setUseTransientmethod) to disable the check for
@Transient
annotations (see this answerfor implementation details). - Use another object than
PublicationVO
as the returned result of yourgetPublicationDetailsJSON
method. You'll have to copy properties from your value object to the object being returned at some point. - 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).
- 配置 Hymanson(使用 HibernateAnnotationIntrospector 的setUseTransient方法)以禁用对
@Transient
注释的检查(有关实现详细信息,请参阅此答案)。 - 使用另一个对象而不是
PublicationVO
方法的返回结果getPublicationDetailsJSON
。您必须将属性从值对象复制到某个时候返回的对象。 - 删除
@Transient
注释并保留该属性(但我会理解这是否不适合您,因为您可能有充分的理由首先将此属性设为 JPA 瞬态)。
Cheers
干杯
回答by Damien Gallagher
Just to add further to the answer provided by m4rtin
只是为了进一步补充 m4rtin 提供的答案
I went with the first approach - Configure Hymanson (using HibernateAnnotationIntrospector's setUseTransient method) to disable the check for @Transient annotations.
我采用了第一种方法 - 配置 Hymanson(使用 HibernateAnnotationIntrospector 的 setUseTransient 方法)来禁用对 @Transient 注释的检查。
In my project I follwed had to follow the following thread to avoid Hymanson serialization on non fetched lazy objects Avoid Hymanson serialization on non fetched lazy objects
在我的项目中,我必须遵循以下线程以避免非获取的惰性对象上的 Hymanson 序列化避免非获取的惰性对象上的 Hymanson 序列化
To configure my project to not ignore transient annotations, I set up the Hibernate4Module as follows
为了配置我的项目不忽略瞬态注释,我设置了 Hibernate4Module 如下
Hibernate4Module hm = new Hibernate4Module();
hm.disable(Feature.USE_TRANSIENT_ANNOTATION);
Thanks for your help on this m4rtin
感谢您对此 m4rtin 的帮助
回答by Fidan Hakaj
I simply added JsonSerializeand JsonDeserializeannotations.
我只是添加了JsonSerialize和JsonDeserialize注释。
@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
回答by Clarke
I use both @Transient and @JsonProperty, then it works!
我同时使用@Transient 和@JsonProperty,然后就可以了!
@Transient
@JsonProperty
private String mapImageSrc;
回答by yue wang
use @JsonIgnore in com.fasterxml.Hymanson.annotation there also is @JsonFormat for Date variable. works for me
在 com.fasterxml.Hymanson.annotation 中使用 @JsonIgnore 也有 @JsonFormat 用于 Date 变量。为我工作
回答by Sapna
Try @JsonView after adding @Transient
添加@Transient 后尝试@JsonView
回答by dave0688
Since no other solution here worked for me, let me post my solution how it did the trick for me:
由于这里没有其他解决方案对我有用,让我发布我的解决方案它是如何为我解决问题的:
@Transient
@JsonSerialize
private String mapImageSrc;
This seems to be the best solution to me as the @JsonSerialize
annotation has been made for that use case.
这对我来说似乎是最好的解决方案,因为@JsonSerialize
已经为该用例制作了注释。
回答by Vic
What it worked for me:
它对我有用:
@Transient
@JsonProperty
in the GETTER (not in the private field definition)
在 GETTER 中(不在私有字段定义中)
AND
和
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
annotating the class
注释类
回答by Alok Singh
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.
感谢 m4rtin。
回答by hizmarck
In my case only works with this:
在我的情况下只适用于这个:
@Transient
@JsonGetter(value = "transientProperty")
public String getSomething() {
return something;
}
I hope this can be useful for someone. Regards.
我希望这对某人有用。问候。