Reputation: 35
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.
Upvotes: 0
Views: 1204
Reputation: 993
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.
Upvotes: 1