您的位置:首页 > Web前端 > JavaScript

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

2016-07-13 23:43 441 查看
@jsonignore的作用
作用是json序列化时将javabean中的一些属性忽略掉,序列化和反序列化都受影响。
http://www.cnblogs.com/toSeeMyDream/p/4437858.html
当表间有One2Many或Many2One时,会发生无限循环的场景,如何破?

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

@JsonIgnore
publicSetxxxs(){
returnthis.xxxYyyy;
}


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

1、@Transient

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

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

@Transient
publicintgetAge(){
 return1+1;
}

Jackson相关:

2、@JsonIgnoreProperties

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

3、@JsonIgnore

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

4、@JsonFormat

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

5、@JsonSerialize

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

6、@JsonDeserialize

此注解用于属性或者setter方法上,用于在反序列化时可以嵌入我们自定义的代码,类似于上面的@JsonSerialize
http://www.cnblogs.com/guijl/p/3855329.html

hibernate懒加载和json序列化冲突

假设某POJO有属性如下:

privateSet<User>users=newHashSet<>(0);

@OneToMany(fetch=FetchType.LAZY,mappedBy="xuser")
publicSet<User>getUsers(){
returnthis.users;
}


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

failedtolazilyinitializeacollectionofrole...


解决方法一:

通过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时该字段被忽略:

importcom.fasterxml.jackson.annotation.JsonIgnore;



privateSet<User>users=newHashSet<>(0);
@JsonIgnore
@OneToMany(fetch=FetchType.LAZY,mappedBy="xuser")
publicSet<User>getUsers(){
returnthis.users;
}



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

解决方法三:

fetch=FetchType.LAZY改为fetch=FetchType.EAGER,但这样会导致每次查询数据库都要立即提取OneToMany的所有对象,所以非常不推荐。
http://www.cnblogs.com/gugia/p/5117735.html
因为懒加载这个对象属性只是一个代理对象,如果json直接当作一个存在的属性去序列化就会出现错误,所以就只能这样了,当然还有其他办法吧

或者在class上加上

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
publicclassProductPrice{



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

@JsonIgnore
publicSet<User>getUsers(){
returnthis.users;
}

实际我们要做的目的就是为了在MappingJackson2HttpMessageConverter通过aop转化为json的时候不去理这个属性
http://www.cnblogs.com/cbread/p/4017987.html
作用是json序列化时将javabean中的一些属性忽略掉,序列化和反序列化都受影响。

如下:

packagecom.hzboy.orm;

importjava.util.List;

importjavax.persistence.CascadeType;
importjavax.persistence.Column;
importjavax.persistence.Entity;
importjavax.persistence.FetchType;
importjavax.persistence.JoinColumn;
importjavax.persistence.JoinTable;
importjavax.persistence.ManyToMany;
importjavax.persistence.ManyToOne;
importjavax.persistence.Table;
importjavax.persistence.Transient;

importorg.codehaus.jackson.annotate.JsonIgnore;
importorg.codehaus.jackson.annotate.JsonIgnoreProperties;
importorg.codehaus.jackson.annotate.JsonManagedReference;

/**
*系统用户实体类
*@authortinner
*
*/
@Entity(name="com.hzboy.orm.User")
@Table(name="sys_user")
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
publicclassUserextendsBaseEntity{

/**
*
*/
privatestaticfinallongserialVersionUID=-1343842065506227012L;

publicUser(){

}

publicUser(Integerid){
this.id=id;
}

//登录名
privateStringloginName;
//密码123456-b594510740d2ac4261c1b2fe87850d08
privateStringpswd;
//姓名
privateStringnickName;
//性别
privateShortsex;
//年龄段
privateStringageStage;
//是否系统管理员
privatebooleansystemAdmin;
//联系电话
privateStringtel;
//Email
privateStringemail;
//是否工程师
privateBooleanisEnginner;
//是否前端客户是则显示前台html,但同时保留后台相关模块
privateBooleanisFrontUser;
//相关部门
privateDepartmentdepartment;
//相关部门前台描述
privateStringdepartmentName;
privateIntegerdepartmentId;
//用户编号
privateStringuserCode;
//附加用于导入
privateStringidCode;
//附加的部门信息用于计算
privateStringdepartmentCode;
@Column(name="login_name")
publicStringgetLoginName(){
returnloginName;
}

publicvoidsetLoginName(StringloginName){
this.loginName=loginName;
}

@Column(name="pswd")
publicStringgetPswd(){
returnpswd;
}

publicvoidsetPswd(Stringpswd){
this.pswd=pswd;
}

@Column(name="nick_name")
publicStringgetNickName(){
returnnickName;
}

publicvoidsetNickName(StringnickName){
this.nickName=nickName;
}

@Column(name="sex")
publicShortgetSex(){
returnsex;
}

publicvoidsetSex(Shortsex){
this.sex=sex;
}

@Column(name="age_stage")
publicStringgetAgeStage(){
returnageStage;
}

publicvoidsetAgeStage(StringageStage){
this.ageStage=ageStage;
}

@Column(name="system_admin")
publicbooleanisSystemAdmin(){
returnsystemAdmin;
}

publicvoidsetSystemAdmin(booleansystemAdmin){
this.systemAdmin=systemAdmin;
}

privateList<Role>roles;

@ManyToMany(fetch=FetchType.LAZY,cascade=(CascadeType.REMOVE))
@JoinTable(name="sys_user_role",joinColumns={@JoinColumn(name="user_id")},inverseJoinColumns={@JoinColumn(name="role_id")})
publicList<Role>getRoles(){
returnroles;
}

publicvoidsetRoles(List<Role>roles){
this.roles=roles;
}

privateInteger[]roleIds;

@Transient
publicInteger[]getRoleIds(){
returnroleIds;
}

publicvoidsetRoleIds(Integer[]roleIds){
this.roleIds=roleIds;
}
@Column(name="email")
publicStringgetEmail(){
returnemail;
}

publicvoidsetEmail(Stringemail){
this.email=email;
}
@Column(name="is_enginner")
publicBooleangetIsEnginner(){
returnisEnginner;
}

publicvoidsetIsEnginner(BooleanisEnginner){
this.isEnginner=isEnginner;
}
@Column(name="is_front_user")
publicBooleangetIsFrontUser(){
returnisFrontUser;
}

publicvoidsetIsFrontUser(BooleanisFrontUser){
this.isFrontUser=isFrontUser;
}

publicStringgetTel(){
returntel;
}

publicvoidsetTel(Stringtel){
this.tel=tel;
}
@JsonIgnore
@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY)
@JoinColumn(name="department_id")
publicDepartmentgetDepartment(){
returndepartment;
}
@JsonManagedReference
publicvoidsetDepartment(Departmentdepartment){
this.department=department;
}

@Transient
publicStringgetDepartmentName(){
returndepartmentName;
}

publicvoidsetDepartmentName(StringdepartmentName){
this.departmentName=departmentName;
}

@Transient
publicIntegergetDepartmentId(){
returndepartmentId;
}

publicvoidsetDepartmentId(IntegerdepartmentId){
this.departmentId=departmentId;
}
@Column(name="user_code")
publicStringgetUserCode(){
returnuserCode;
}

publicvoidsetUserCode(StringuserCode){
this.userCode=userCode;
}
@Column(name="id_from_import")
publicStringgetIdCode(){
returnidCode;
}

publicvoidsetIdCode(StringidCode){
this.idCode=idCode;
}
publicStringgetDepartmentCode(){
returndepartmentCode;
}

publicvoidsetDepartmentCode(StringdepartmentCode){
this.departmentCode=departmentCode;
}
}


上个实体User中的department属性就在getDepartment属性上加了@JsonIgnore,这个时候从后台推数据到前台的时候,就会把department这个引用属性给忽略掉。
http://www.mamicode.com/info-detail-578520.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: