【问题标题】:java.lang.StackOverflowError occuring with Hibernate and three tablesjava.lang.StackOverflowError 发生在 Hibernate 和三个表中
【发布时间】:2014-03-14 13:49:25
【问题描述】:

我正在构建一个应用程序,该应用程序要求设备可以向 Web 服务发送请求,询问它是否可以运行 Jasmine 单元测试。这一点有效。什么不起作用,如果我让 Hibernate 检索完整的数据列表,我会收到 StackOverFlowError。

我已经包含了这三个实体。

@Entity
@Table(name = "device")
    public class Device {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "device_id")
    private Integer id;

    @Column(name = "device_name")
    private String deviceName;

    @OneToMany(mappedBy = "device", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Test> tests;

}

@Entity
@Table(name = "test")
public class Test {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "test_id")
    private Integer id;

    @Column(name = "test_name")
    private String testName;

    @OneToMany(mappedBy = "test", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Test_Case> testcases;

    @ManyToOne
    @JoinColumn(name = "device_id")
    private Device device;

}

@Entity
@Table(name = "test_case")
public class Test_Case {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "test_case_id")
    private String testCaseId;

    @Column(name = "can_run")
    private String canRun;

    @ManyToOne
    @JoinColumn(name = "test_id")
    private Test test;
}

所以重申一下。设备包含一组测试,测试类似于条形码、扫描仪等,每个测试包含一组测试用例。一个测试用例是对 Barcode 等的单独测试。数据库的架构如下所示。

CREATE TABLE device (
    device_id int(11) NOT NULL AUTO_INCREMENT,
    device_name varchar(100) DEFAULT NULL,
    PRIMARY KEY(device_id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

CREATE TABLE test(
    test_id int(11) NOT NULL AUTO_INCREMENT,
    test_name varchar(100) DEFAULT NULL,
    device_id int(11) NOT NULL,
    PRIMARY KEY(test_id),
    INDEX FK_DEVC (device_id),
    CONSTRAINT FK_DEVC FOREIGN KEY (device_id) REFERENCES device (device_id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE test_case (
    id int(11) NOT NULL AUTO_INCREMENT,
    test_case_id varchar(100) DEFAULT NULL,
    can_run varchar(1) DEFAULT NULL,
    test_id int(11) NOT NULL,
    PRIMARY KEY(id),
    INDEX FK_TEST (test_id),
    CONSTRAINT FK_TEST FOREIGN KEY (test_id) REFERENCES test (test_id)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

当我让 Hibernate 检索所有内容时,会生成以下查询。

Hibernate: select device0_.device_id as device_i1_0_, device0_.device_name as device_n2_0_ from device device0_

Hibernate: select tests0_.device_id as device_i3_0_1_, tests0_.test_id as test_id1_2_1_, tests0_.test_id as test_id1_2_0_, tests0_.device_id as device_i3_2_0_, tests0_.test_name as test_nam2_2_0_ from test tests0_ where tests0_.device_id=?

Hibernate: select testcases0_.test_id as test_id4_2_1_, testcases0_.id as id1_3_1_, testcases0_.id as id1_3_0_, testcases0_.can_run as can_run2_3_0_,testcases0_.test_id as test_id4_3_0_, testcases0_.test_case_id as test_cas3_3_0_ from test_case testcases0_ where testcases0_.test_id=?

这会在生成结果时导致 StackOverflow,在查看代码几天并遵循其他答案的建议后,我无法停止产生该错误。

调用由 Spring MVC Restful 接口生成,该接口使用 Jackson 将响应主体发回以将输出转换为 JSON。

我在这里做错了什么明显的事情吗?对于那些感兴趣的人,我正在使用 Spring 3.2.7、Hibernate 4.2.8 和 MySQL 5.something。

【问题讨论】:

    标签: java mysql json spring hibernate


    【解决方案1】:

    Jackson 的连载正在循环中。序列化 Test Jackson 时也会序列化 Test_Case 对象。但是为了序列化一个 Test_Case,Jackson 也尝试序列化 Test 对象。

    可以在Test_Case的成员test中添加@JsonIgnore注解来打破这个圈子。

    Test类中的成员设备也需要@JsonIgnore注解。

    【讨论】:

      猜你喜欢
      • 2020-07-20
      • 2012-09-16
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-07
      • 2016-07-12
      相关资源
      最近更新 更多