【问题标题】:stackoverflow error during json conversion (hibernate bi-directional mapping)json转换期间stackoverflow错误(休眠双向映射)
【发布时间】:2013-10-01 06:05:39
【问题描述】:

我有两个实体类:带有问题列表的User 类和带有用户属性的Question

用户类声明:

 @Entity
    @Table(schema="test",name="so_user")
    public class User {
    private List<Question> questions;
    //other attributes
            @OneToMany(cascade=CascadeType.ALL)
        @PrimaryKeyJoinColumn   
        public List<Question> getQuestions() {
            return questions;
        }
    //.. other methods
    }   

问题类声明:

@Entity
@Table(schema="test")
public class Question {
private User askedBy;
//other attributes
  @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
  @PrimaryKeyJoinColumn
  public User getAskedBy() {
    return askedBy;
  }

//.. other methods
}   

当我尝试使用 Gson library 将用户对象转换为 Json 时,它会给出 stackoverflow error。原因:用户有一个问题列表,每个问题依次有 用户属性(用于在休眠中进行双向映射)。

测试代码:

public class MappingTest {
    public static void main(String[] args) {
        List<User> users = null;
        User user = null;
        //populate some users
        for (int i = 0; i < 10; i++) {
            if (i == 0)
                users = new ArrayList<User>();
            user = new User();
            List<Question> questions = null;
            Question question = null;
            //create dummy questions
            for (int questionCount = 0; questionCount < 5; questionCount++) {
                if(questionCount==0)
                    questions = new ArrayList<Question>();
                question = new Question();
                question.setAskedBy(user);
                System.out.println("question added is "+question);
                questions.add(question);
            }
            user.setQuestions(questions);
            users.add(user);
            System.out.println("user added is "+user);
        }
        //TODO
        System.out.println(users);
        Gson gson = new Gson();
        System.out.println(gson.toJson(users));

    }
}

控制台日志:

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuffer.append(Unknown Source)
    at java.io.StringWriter.write(Unknown Source)
    at com.google.gson.stream.JsonWriter.string(JsonWriter.java:534)
    at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402)
    at com.google.gson.stream.JsonWriter.value(JsonWriter.java:495)
    at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:268)
    at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:253)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)

【问题讨论】:

标签: java hibernate gson bidirectional stack-overflow


【解决方案1】:

将 Jackson API 放入您的 (com.fasterxml.jackson) 应用程序中并在实际中使用此注释

@JsonBackReference 对倒置类(1-To-N 情况下的列表或集合)的引用。

@JsonManagedReference 到 mappedBy 类(在 1-To-N 的情况下为单个对象)。

你的情况

@OneToMany(cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn
@JsonManagedReference   
public List<Question> getQuestions() {
     return questions;
}

______________________________________


@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@PrimaryKeyJoinColumn
@JsonBackReference
public User getAskedBy() {
    return askedBy;
}

您需要使用 Jackson(而不是 gson)打印 json。

它适用于我在序列化中的双向递归。

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多