![](/img/trans.png)
[英]Hibernate: java.lang.StackOverflowError while trying to persist an object graph
[英]java.lang.StackOverflowError while accessing data using hibernate
當我嘗試在休眠狀態下加入2個表時出現錯誤。 復制的代碼在這里。
/*ADDRESS table entity mapping */
@Entity
@Table(name = "ADDRESS")
public class AddressEntity {
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinColumn(name = "user_id")
private UserEntity user;
// setters and getters and other attributes.
}
/* APPUSER table entity mapping */
@Entity
@Table(name = "APPUSER")
public class UserEntity {
@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long userId;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
private Set<AddressEntity> addresses;
// setters and getters and other attributes.
}
問題在於地址和用戶實體的映射。 每個用戶可以有多個地址,這是必需的。 請幫忙。
下面是復制表DDL語句。它是用戶和地址表之間的一對多關系。
SQL表:
CREATE TABLE `appuser` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) DEFAULT NULL,
`email_address` varchar(1024) NOT NULL,
`password` varchar(1024) NOT NULL,
`active` tinyint(1) DEFAULT '1',
`popularity_rating` int(11) DEFAULT NULL,
`join_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
CREATE TABLE `address` (
`address_id` int(11) NOT NULL AUTO_INCREMENT,
`address_line1` varchar(38) NOT NULL,
`address_line2` varchar(38) NOT NULL,
`city` varchar(38) NOT NULL,
`state` varchar(38) NOT NULL,
`zip` varchar(10) NOT NULL,
`address_type` varchar(45) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`address_id`),
KEY `fk_address_user_idx` (`user_id`),
CONSTRAINT `fk_address_user` FOREIGN KEY (`user_id`) REFERENCES `appuser` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
上面連接ADDRESS和USER表給了我StackOverflowError。
預期結果是:
{
"userId": 1,
"firstName": "alb",
"lastName": "va",
"emailAddress": "alb@va.com",
"password": "albva",
"addresses": [
{
"addressLine1": "222 plano pkwy",
"addressLine2": "apt 22",
"city": "plano",
"state": "tx",
"zip": "75034",
"country": null
}, {
"addressLine1": "555 plano pkwy",
"addressLine2": "apt 11",
"city": "plano",
"state": "tx",
"zip": "75024",
"country": null
}
],
"popularityRating": 6,
"joinDate": 1504897922000,
"roles": []
}
結果我在調用Web服務時遇到一個無限循環。這是導致堆棧溢出錯誤的原因:
{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user":{"userId":2,"firstName":"rax","lastName":"tax","emailAddress":"rax@tax.com","password":"raxtax","addresses":[{"addressLine1":"2001 spring creek","addressLine2":"apt 724","city":"plano","state":"tx","zip":"75074","country":null,"addressType":null,"user": ...
如前所述,當您試圖連接兩個相互依賴的表時,必然會發生無限循環,因為表A試圖從表B中獲取數據。表B依賴於表A並嘗試從中獲取數據。表A.它遇到無限循環,並因此繼續引起堆棧溢出異常。 解決方案是用@JsonManagedReference和@JsonBackReference注釋字段。 這樣,標有@JsonManagedReference的類將被序列化,而標有@JsonBackReference的類則不會被序列化。 這打破了無限循環。 在您的代碼中,您的實體將如下所示;
/*ADDRESS table entity mapping */
@Entity
@Table(name = "ADDRESS")
public class AddressEntity {
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinColumn(name = "user_id")
@JsonBackReference
private UserEntity user;
// setters and getters and other attributes.
}
/* APPUSER table entity mapping */
@Entity
@Table(name = "APPUSER")
public class UserEntity {
@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long userId;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
@JsonManagedReference
private Set<AddressEntity> addresses;
// setters and getters and other attributes.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.