Java JPA瞬态注释和JSON
这是关于JPA瞬态注释的以下问题的后续问题 我有一个不想持久化的瞬态变量,它用瞬态注释标记。 但是,当我想从rest控制器生成JSON时,这个临时变量在输出的JSON中不可用 POJO PublicationVO是直截了当的,没有奇特的属性,只有一些私有属性(持久化的),带有getter和setter以及1个临时变量Java JPA瞬态注释和JSON,java,json,spring,rest,jackson,Java,Json,Spring,Rest,Jackson,这是关于JPA瞬态注释的以下问题的后续问题 我有一个不想持久化的瞬态变量,它用瞬态注释标记。 但是,当我想从rest控制器生成JSON时,这个临时变量在输出的JSON中不可用 POJO PublicationVO是直截了当的,没有奇特的属性,只有一些私有属性(持久化的),带有getter和setter以及1个临时变量 @RequestMapping(value = { "{publicationId}"}, method = RequestMethod.GET, produces = "app
@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 + "]";
}
}
Hibernate4Module hm = new Hibernate4Module();
hm.disable(Feature.USE_TRANSIENT_ANNOTATION);
当我在日志中看到publicationVO的调试语句时,瞬态变量包含在输出中,但在客户端代码中,瞬态变量不包含在json响应中
非常感谢您的帮助
谢谢,,
Damien与我在评论中告诉您的相反,Jackson在用于序列化实体类实例时似乎确实关心JPA注释,这要归功于 在该模块中,有一个文档称为 简单的AnnotationIntrospector,它增加了对使用瞬态转换的支持 表示可忽略字段(与Jackson和/或JAXB一起) 注释) 正如您所见,Jackson的默认行为是检查它能找到的任何
@Transient
注释
因此,最终,您的问题可以通过以下三种方式之一解决:
@Transient
注释的检查(有关实现细节,请参阅)PublicationVO
以外的另一个对象作为getPublicationDetailsJSON
方法的返回结果。您必须将属性从值对象复制到某个时刻返回的对象@Transient
注释并持久化该属性(但如果这不是您的选项,我会理解,因为您可能有充分的理由首先使该属性成为JPA Transient)干杯只是为了进一步补充m4rtin提供的答案 我使用了第一种方法——配置Jackson(使用HibernateAnnotationIntrospector的setUseTransive方法)来禁用@Transient注释的检查
@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
在我的项目中,我必须遵循以下线程,以避免对未获取的惰性对象进行jackson序列化
为了将我的项目配置为不忽略瞬态注释,我设置了Hibernate4模块,如下所示
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 + "]";
}
}
Hibernate4Module hm = new Hibernate4Module();
hm.disable(Feature.USE_TRANSIENT_ANNOTATION);
感谢您在此m4rtin上的帮助。我只是添加了一些注释
@Transient
@JsonSerialize
@JsonDeserialize
private String myField;
我同时使用@Transient和@JsonProperty,然后它就可以工作了
@Transient
@JsonProperty
private String mapImageSrc;
在com.fasterxml.jackson.annotation中使用@JsonIgnore 日期变量还有@JsonFormat。
适用于我在添加@Transient后尝试@JsonView因为这里没有其他解决方案适用于我,让我发布我的解决方案,它是如何为我发挥作用的:
@Transient
@JsonSerialize
private String mapImageSrc;
对于我来说,这似乎是最好的解决方案,因为
@JsonSerialize
注释已经针对该用例进行了注释。它对我的作用:
@Transient
@JsonProperty
在GETTER中(不在私有字段定义中)
及
注释类我也有同样的问题。以下解决方案对我有效:
@Bean
public Module hibernate5Module() {
Hibernate5Module hnetModule = new Hibernate5Module();
hnetModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
return hnetModule;
}
多亏了m4rtin。在我的情况下,仅适用于以下情况:
@Transient
@JsonGetter(value = "transientProperty")
public String getSomething() {
return something;
}
我希望这对某人有用。
关于。您能否编辑您的问题并发布PublicationVO的代码?没有被序列化的瞬态变量是否有合适的getter?@m4rtin-i刚刚包含了publicationVo类。是的,瞬态变量有一个getter方法。正如我在你的问题中看到的一些Spring MVC注释和Spring标记一样,你能确认JSON的序列化是由Jackson库完成的吗?是的,很抱歉,序列化是通过Jackson完成的。如果是这样的话,我需要一个非瞬态的磁场,我可以试着找出一个解决方法,但我希望有一个更干净的方法,这是一个公平的观点。我将尝试手动添加数据库列,删除临时注释,然后查看它是否有任何区别,然后返回给您。我会在早上尝试第1步,如果这不起作用,我想第2步可能是下一个逻辑步骤。非常感谢您提供的信息。第4步,它对我们很有效。杰克逊甚至无法选择关心hibernate的注释。这些人高还是什么?很高兴你找到了关于第一种方法的实施细节,我将编辑我的答案,为你的答案添加一个参考,这肯定会对寻求解决方案1的人有所帮助。最后是一些有用的东西!我用这个设置所需的各种文件创建了一个。JsonSerialize和JsonProperty似乎都能工作。我想知道是否有细微的差别,如果一个优于另一个。你甚至可以使用@JsonProperty(access=access.WRITE_ONLY)或@JsonProperty(access=access.READ_ONLY)来优化访问。这是我在使用@Transient for the my field时唯一有效的方法。谢谢,它成功了。这有助于分别定义数据库中应该保留的内容和JSON中应该保留的内容。我不知道它是否有效,但似乎我们最终在实体中混合了跨层信息。Transient用于db层(最底层),而JsonSerialize应位于UI/客户端层。我必须确保为
@Json*
注释导入了正确的包org.springframework.cloud.cloudfoundry.com.fasterxml.jackson.databind.annotation
不起作用,但是com.fasterxml.jackson.databind.annotation.
起作用了。使用注释来获得琐碎的答案和建议。我可以问一下为什么否决票?这对我有效,必须在类级别添加@jsonautodect
,谢谢!