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

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

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

@Transient
public 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 中添加代码如下:

Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释
<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>
Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释

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

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

解决方法二:

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

Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释
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;
}
Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释

注意引入的类是 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 注解

@JsonIgnore
public 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

上一篇:使用CGLIB实现动态代理


下一篇:Spring进阶之路(10)-Advice简单介绍以及通过cglib生成AOP代理对象