无限递归杰克逊JSON,Spring MVC 4.2和Hibernate JPA问题 [英] Infinite Recursion with Jackson JSON, Spring MVC 4.2 and Hibernate JPA issue

查看:606
本文介绍了无限递归杰克逊JSON,Spring MVC 4.2和Hibernate JPA问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当Spring MVC尝试通过jackson 2.6.1将具有双向关联的JPA对象转换为JSON时,我不断收到

  org.springframework.http.converter.HttpMessageNotWritableException:无法写入内容:无限递归(StackOverflowError)

第一个实体是:

  import com.fasterxml.jackson.annotation.JsonManagedReference; 
import javax.persistence.Entity;
import javax.persistence.Table;
...

@Entity
@Table(name =user)
public class用户实现java.io.Serializable {
private Integer用户名;
@JsonManagedReference
private UserClass userClass;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name =userId,unique = true,nullable = false)
public Integer getUserId ){
返回this.userId;


@ManyToOne()
@JoinColumn(name =userClassId)

public UserClass getUserClass(){
return this .userClass;
}
.......
}

第二个是:

  import com.fasterxml.jackson.annotation.JsonManagedReference; 
import javax.persistence.Entity;
import javax.persistence.Table;
...

@Entity
@Table(name =user_class)
public class UserClass implements java.io.Serializable {

private Integer userClassId;
@JsonBackReference
私人列表< User> users = new ArrayList< User>(0);

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name =userClassId,unique = true,nullable = false)
public Integer getUserClassId ){
返回this.userClassId;
}


@OneToMany(fetch = FetchType.LAZY,mappedBy =userClass)
public List< User> getUsers(){
返回this.users;
}

这里是依赖项:

 <依赖关系> 

< dependency>
< groupId> junit< / groupId>
< artifactId> junit< / artifactId>
< version> 3.8.1< / version>
< scope> test< / scope>
< /依赖关系>

< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-webmvc< / artifactId>
< version> 4.2.0.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-orm< / artifactId>
< version> 4.2.0.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-oxm< / artifactId>
< version> 4.2.0.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework.data< / groupId>
< artifactId> spring-data-jpa< / artifactId>
< version> 1.8.2.RELEASE< / version>
<排除项>
<排除>
< groupId> org.springframework< / groupId>
< artifactId> spring-aop< / artifactId>
< /排除>
< /排除>
< /依赖关系>


< dependency>
< groupId> javax.servlet< / groupId>
< artifactId> servlet-api< / artifactId>
< scope>提供< / scope>
< version> 2.5< / version>
< /依赖关系>
< dependency>
< groupId> javax.servlet< / groupId>
< artifactId> jstl< / artifactId>
< version> 1.2< / version>
< /依赖关系>

< dependency>
< groupId> cglib< / groupId>
< artifactId> cglib< / artifactId>
< version> 3.1< / version>
< /依赖关系>

< dependency>
< groupId> log4j< / groupId>
< artifactId> log4j< / artifactId>
< version> 1.2.17< / version>
< /依赖关系>

< dependency>
< groupId> com.thoughtworks.xstream< / groupId>
< artifactId> xstream< / artifactId>
< version> 1.4.8< / version>
< /依赖关系>
< dependency>
< groupId> com.fasterxml.jackson.core< / groupId>
< artifactId> jackson-core< / artifactId>
< version> 2.6.1< / version>
< /依赖关系>
< dependency>
< groupId> com.fasterxml.jackson.core< / groupId>
< artifactId> jackson-databind< / artifactId>
< version> 2.6.1< / version>
< /依赖关系>
< dependency>
< groupId> com.fasterxml.jackson.datatype< / groupId>
< artifactId> jackson-datatype-hibernate4< / artifactId>
< version> 2.6.1< / version>
< /依赖关系>



< dependency>
< groupId> mysql< / groupId>
< artifactId> mysql-connector-java< / artifactId>
< version> 5.1.34< / version>
< /依赖关系>

< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-core< / artifactId>
< version> 4.3.10.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-entitymanager< / artifactId>
< version> 4.3.10.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-validator< / artifactId>
< version> 5.1.3.Final< / version>
< /依赖关系>

< dependency>
< groupId> org.apache.tiles< / groupId>
< artifactId> tiles-core< / artifactId>
< version> 3.0.5< / version>
< /依赖关系>
< dependency>
< groupId> org.apache.tiles< / groupId>
< artifactId> tiles-jsp< / artifactId>
< version> 3.0.5< / version>
< /依赖关系>
< dependency>
< groupId> org.apache.tiles< / groupId>
< artifactId> tiles-api< / artifactId>
< version> 3.0.5< / version>
< /依赖关系>
< dependency>
< groupId> org.apache.tiles< / groupId>
< artifactId> tiles-template< / artifactId>
< version> 3.0.5< / version>
< /依赖关系>

< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> jcl-over-slf4j< / artifactId>
< version> 1.7.12< / version>
< /依赖关系>
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> slf4j-api< / artifactId>
< version> 1.7.12< / version>
< /依赖关系>
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> slf4j-simple< / artifactId>
< version> 1.7.12< / version>
< /依赖关系>

< dependency>
< groupId> com.google.guava< / groupId>
< artifactId>番石榴< / artifactId>
< version> 18.0< / version>
< /依赖关系>


< / dependencies>

为防止递归,我使用了@JsonIgnore,@JsonIdentityInfo和XmlTransient他们不工作,服务器报告这个错误。有人可以帮我吗?

谢谢。

编辑:
和堆栈轨迹:

  org.springframework.http.converter.HttpMessageNotWritableException:无法写入内容:无限递归(StackOverflowError)(通过引用链:
sss.com.model.UserClass [ 用户] - > org.hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [ UserClass的] - > sss.com.model .UserClass [users] - >
org.hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [userClass] - > sss.com.model。 UserClass的[ 用户] - > org.hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [ UserClass的] - > sss.com.model.UserClass [ 用户 ] ...。
嵌套的异常是com.fasterxml.jackson.databind.JsonMappingException:无限递归(StackOverflowError)(通过引用链:
sss.com.model.UserClass [users] - > ; org.hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [ UserClass的] - > sss.com.m odel.UserClass [ 用户] - >
org.hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [userClass] - > sss.com.model.UserClass [users] - > org .hibernate.collection.internal.PersistentBag [0] - > sss.com.model.User [userClass] - > sss.com.model.UserClass [users] ...。与根源
java.lang.StackOverflowError的$ B $ LT b。在产生java.io.IOException&;初始化>(IOException.java:58)
。在com.fasterxml.jackson.core.JsonProcessingException< ; init>(JsonProcessingException.java:25)
at com.fasterxml.jackson.core.JsonProcessingException。< init>(JsonProcessingException.java:41)
at com.fasterxml.jackson.databind.JsonMappingException 。< init>(JsonMappingException.java:143)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:689)
at com.fasterxml.jackson。在com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
(CollectionSerializer.java:149)
。在com.fasterxml。 jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:111)
在com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:656)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java: 675)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer。 Java的:在com.fasterxml.jackson.databind.ser.std.CollectionSerializer在com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents 157)
(CollectionSerializer.java:149)
。 serialize(CollectionSerializer.java:111)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
在com.fasterxml.jackson.databind.ser.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)







解决方案:
在我的原始实体中,我有5个双向关系,但是只是,我被注释了一个关系。原因是tomcat在结果页面没有打印异常,我也没有检查tomcat的日志文件。

code> @JsonIgnore

  @JsonIgnore 
@OneToMany(fetch = FetchType .LAZY,mappedBy =userClass)
public List< User> getUsers(){
返回this.users;
}

这会忽略延迟加载对象并修复您的问题。



更新




When Spring MVC try to convert a JPA object that has a bi-directional association into JSON by jackson 2.6.1 , I keep getting

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError)

and first entity is:

import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.Entity;
import javax.persistence.Table;
...

@Entity
@Table(name = "user")
public class User implements java.io.Serializable {
    private Integer userId;
    @JsonManagedReference
    private UserClass userClass;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "userId", unique = true, nullable = false)
public Integer getUserId() {
    return this.userId;
}

@ManyToOne()
@JoinColumn(name = "userClassId")

public UserClass getUserClass() {
    return this.userClass;
}
.......
}

the second is:

 import com.fasterxml.jackson.annotation.JsonManagedReference;
 import javax.persistence.Entity;
 import javax.persistence.Table;
 ...

@Entity
@Table(name = "user_class")
public class UserClass implements java.io.Serializable {

private Integer userClassId;
@JsonBackReference
private List<User> users = new ArrayList<User>(0);

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "userClassId", unique = true, nullable = false)
public Integer getUserClassId() {
    return this.userClassId;
}


@OneToMany(fetch = FetchType.LAZY, mappedBy = "userClass")
public List<User> getUsers() {
     return this.users;
}

and here is dependencies:

<dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.8.2.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aop</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-hibernate4</artifactId>
            <version>2.6.1</version>
        </dependency>



        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.3.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-core</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-api</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-template</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.12</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>


    </dependencies>

I used "@JsonIgnore", "@JsonIdentityInfo" and "XmlTransient" for prevent recursion but both of them not working and the server report this error. Can someone help me?

Thanks.

Edit: And Stack trace:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain:
sss.com.model.UserClass["users"]->org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]->
org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]->org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]... .
 nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: 
sss.com.model.UserClass["users"]->org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]->
org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]->org.hibernate.collection.internal.PersistentBag[0]->sss.com.model.User["userClass"]->sss.com.model.UserClass["users"]... . with root cause
 java.lang.StackOverflowError
    at java.io.IOException.<init>(IOException.java:58)
    at com.fasterxml.jackson.core.JsonProcessingException.<init>(JsonProcessingException.java:25)
    at com.fasterxml.jackson.core.JsonProcessingException.<init>(JsonProcessingException.java:41)
    at com.fasterxml.jackson.databind.JsonMappingException.<init>(JsonMappingException.java:143)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:689)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:111)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:656)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:656)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:111)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:656)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
...

SOLVED: In my original entity I have 5 bidirectional relation but, just, I was annotated one relation. The reason is tomcat didn't print exception in result page and i don't check tomcat log file.

解决方案

Just put @JsonIgnore

@JsonIgnore
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userClass")
public List<User> getUsers() {
     return this.users;
}

This will ignore lazy load object and fix your issue.

Update

  • According to Udara Seneviratne answer, You can handle bi-directional relationship by @JsonManagedReference, @JsonBackReference.

这篇关于无限递归杰克逊JSON,Spring MVC 4.2和Hibernate JPA问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆