简体   繁体   中英

java.lang.StackOverflowError occuring with Hibernate and three tables

I'm building an application that requires that a device can send a request to a webservice asking whether it can run a Jasmine unit test. This bit works. What doesn't work, is if I ask Hibernate to retrieve a full list of data, I get a StackOverFlowError.

I've included the three entities.

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

So to reiterate. Device contains a set of Test, a Test being something like Barcode, Scanner, etc, and each Test contains a set of Test Cases. A test case being an individual test for Barcode, etc. The schema for the database looks like the following.

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;

When I ask Hibernate to retrieve everything, I get the following queries generated.

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=?

This causes a StackOverflow when the results are being generated, and after looking over the code for a few days and following advice from other answers, I just cannot get this to stop producing that error.

The call is being generated by a Spring MVC Restful interface that sends response body back using Jackson to convert the output to JSON.

Is there anything obvious that I am doing wrong here? For those interested, I'm using Spring 3.2.7, Hibernate 4.2.8 and MySQL 5.something.

The serialization by Jackson is running in circles. When serializing the Test Jackson also serializes Test_Case objects. But to serialize a Test_Case Jackson also tries to serialize the Test object.

You can add a @JsonIgnore annotation to the member test in Test_Case to break this circle.

The member device in the class Test also needs the @JsonIgnore annotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM