Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释

xiaoxiao2021-02-28  44

转自:https://www.cnblogs.com/softidea/p/5668697.html

@jsonignore的作用作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。

http://www.cnblogs.com/toSeeMyDream/p/4437858.html当表间有One2Many或Many2One时,会发生无限循环的场景,如何破?

只要在Set方法前增加以下注解即可:

@JsonIgnore public Set xxxs() { return this.xxxYyyy; }

http://www.cnblogs.com/tompandas/p/4618668.html

 

 

1、@Transient

@Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性;如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则ORM框架默认其注解为@Basic;

//表示该字段在数据库表中没有

@Transientpublic int getAge() { return 1+1;}

 

Jackson相关:

2、@JsonIgnoreProperties

此注解是类注解,作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。

 

3、@JsonIgnore

此注解用于属性或者方法上(最好是属性上),作用和上面的@JsonIgnoreProperties一样。

 

4、@JsonFormat

此注解用于属性或者方法上(最好是属性上),可以方便的把Date类型直接转化为我们想要的模式,比如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")

 

5、@JsonSerialize

此注解用于属性或者getter方法上,用于在序列化时嵌入我们自定义的代码,比如序列化一个double时在其后面限制两位小数点。

 

6、@JsonDeserialize

此注解用于属性或者setter方法上,用于在反序列化时可以嵌入我们自定义的代码,类似于上面的@JsonSerialize

http://www.cnblogs.com/guijl/p/3855329.html

 

hibernate懒加载和json序列化冲突

-------------------------------------

假设某 POJO 有属性如下:

private Set<User> users = new HashSet<>(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set<User> getUsers() { return this.users; }

如果我们使用jackson将其序列化,运行时会报错:

failed to lazily initialize a collection of role ...

 

解决方法一:

通过 Hibernate 的 OpenSessionInViewFilter 使得 FetchType 为 LAZY 的属性在序列化时为空,在 web.xml 中添加代码如下:

<filter> <filter-name>openSession</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>false</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSession</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

尽管 users 为空,但字段依然保留,对应输出:

{...,"users":[],...}

 

解决方法二:

在属性的 get 方法之前加上注解 @JsonIgnore,如此在转换为 JSON 时该字段被忽略:

import com.fasterxml.jackson.annotation.JsonIgnore; … private Set<User> users = new HashSet<>(0); @JsonIgnore @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set<User> getUsers() { return this.users; } …

注意引入的类是 com.fasterxml.jackson.annotation.JsonIgnore,如果使用 org.codehaus.jackson.annotate.JsonIgnore 则不能生效,见 Spring @JsonIgnore not working 。

 

解决方法三:

fetch = FetchType.LAZY 改为 fetch = FetchType.EAGER,但这样会导致每次查询数据库都要立即提取 OneToMany 的所有对象,所以非常不推荐

http://www.cnblogs.com/gugia/p/5117735.html

 

因为懒加载这个对象属性只是一个代理对象,如果json直接当作一个存在的属性去序列化就会出现错误,所以就只能这样了,当然还有其他办法吧

或者在class上加上

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})public class ProductPrice {

或者在这个对象的属性上面增加 @JsonIgnore 注解

@JsonIgnorepublic Set<User> getUsers() {return this.users;}

实际我们要做的目的就是为了在MappingJackson2HttpMessageConverter通过aop转化为json的时候不去理这个属性

http://www.cnblogs.com/cbread/p/4017987.html

作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。

如下:

package com.hzboy.orm; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Transient; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonManagedReference; /** * 系统用户实体类 * @author tinner * */ @Entity(name = "com.hzboy.orm.User") @Table(name = "sys_user") @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class User extends BaseEntity { /** * */ private static final long serialVersionUID = -1343842065506227012L; public User() { } public User(Integer id) { this.id = id; } // 登录名 private String loginName; // 密码123456-b594510740d2ac4261c1b2fe87850d08 private String pswd; // 姓名 private String nickName; // 性别 private Short sex; // 年龄段 private String ageStage; // 是否系统管理员 private boolean systemAdmin; //联系电话 private String tel; //Email private String email; //是否工程师 private Boolean isEnginner; //是否前端客户 是则显示前台html,但同时保留后台相关模块 private Boolean isFrontUser; //相关部门 private Department department; //相关部门前台描述 private String departmentName; private Integer departmentId; //用户编号 private String userCode; //附加用于导入 private String idCode; //附加的部门信息 用于计算 private String departmentCode; @Column(name = "login_name") public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } @Column(name = "pswd") public String getPswd() { return pswd; } public void setPswd(String pswd) { this.pswd = pswd; } @Column(name = "nick_name") public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @Column(name = "sex") public Short getSex() { return sex; } public void setSex(Short sex) { this.sex = sex; } @Column(name = "age_stage") public String getAgeStage() { return ageStage; } public void setAgeStage(String ageStage) { this.ageStage = ageStage; } @Column(name = "system_admin") public boolean isSystemAdmin() { return systemAdmin; } public void setSystemAdmin(boolean systemAdmin) { this.systemAdmin = systemAdmin; } private List<Role> roles; @ManyToMany(fetch = FetchType.LAZY, cascade = (CascadeType.REMOVE)) @JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") }) public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } private Integer[] roleIds; @Transient public Integer[] getRoleIds() { return roleIds; } public void setRoleIds(Integer[] roleIds) { this.roleIds = roleIds; } @Column(name="email") public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Column(name="is_enginner") public Boolean getIsEnginner() { return isEnginner; } public void setIsEnginner(Boolean isEnginner) { this.isEnginner = isEnginner; } @Column(name="is_front_user") public Boolean getIsFrontUser() { return isFrontUser; } public void setIsFrontUser(Boolean isFrontUser) { this.isFrontUser = isFrontUser; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } @JsonIgnore @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) @JoinColumn(name="department_id") public Department getDepartment() { return department; } @JsonManagedReference public void setDepartment(Department department) { this.department = department; } @Transient public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } @Transient public Integer getDepartmentId() { return departmentId; } public void setDepartmentId(Integer departmentId) { this.departmentId = departmentId; } @Column(name="user_code") public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } @Column(name="id_from_import") public String getIdCode() { return idCode; } public void setIdCode(String idCode) { this.idCode = idCode; } public String getDepartmentCode() { return departmentCode; } public void setDepartmentCode(String departmentCode) { this.departmentCode = departmentCode; } }

上个实体User中的  department属性就在getDepartment属性上加了  @JsonIgnore,这个时候从后台推数据到前台的时候,就会把department这个引用属性给忽略掉。

http://www.mamicode.com/info-detail-578520.html

转载请注明原文地址: https://www.6miu.com/read-2630842.html

最新回复(0)