问题描述
当我尝试具有引用 Product
和 Product
的 Order
时,出现 StackOverflowError
引用 Order
.我知道这是由于有一个循环参考,但是我不确定如何解决它.我是ORM的新手,但不是SQL/Schema Design的新手:通常,我会有一个 Ordered_Products
表,该表将 Order
映射到 Product
,但我认为Hibernate会自动为我解决这个问题.
I get a StackOverflowError
when attempting to have an Order
which references a Product
, and a Product
that references an Order
. I know this is due to having a circular reference, but I am unsure as to how to fix it. I'm new to ORMs but not to SQL/Schema Design: typically, I would have a Ordered_Products
table which maps an Order
to a Product
, but I thought Hibernate would automagically take care of that for me.
Product
都具有唯一的ID(这些ID在应用程序外部生成),因此没有两个 Product
是相同的. Order
ID也会在应用程序外部生成(我将在此管道的较早过程中从CSV导入此数据).
Product
s all have unique IDs (these are generated outside the app), so no two Product
s are the same. Order
IDs are also generated outside the app (I will be importing this data from a CSV in an earlier process in this pipeline).
有人可以协助我们前进吗?
Could someone assist with moving forward?
@Entity
@Table(name = "Orders")
class Order implements Serializable {
private static final long serialVersionUID = 2916987431893884948L;
@Id
@Column(name="id")
private Long id;
@Column(name="contactName")
private String contactName;
@OneToMany(mappedBy = "order", fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Product> products;
// ...plain old getters and setters omitted...
public Set<Product> getProducts() {
// Should this be done at the member variable declaration?
if (null == products) {
this.products = new HashSet<Product>();
}
return products;
}
public void addProduct(Product p) {
p.setOrder(this);
getProducts().add(p);
}
public String toString() {
/* plain old to String which prints all member vars */
}
}
Product.java
@Entity
@Table(name = "Products")
public class Product implements Serializable {
private static final long serialVersionUID = 663408095532480033L;
@Id
@Column(name="id")
private String id;
@Column(name="size")
private Size size;
@OneToOne
@JoinColumn(name="order_id", nullable=false)
private Order order;
// ...plain old getters and setters...
public enum Size {
EMPTY,
XXSMALL,
XSMALL,
SMALL,
MEDIUM,
LARGE
}
public String toString() {
/* plain old to String which prints all member vars */
}
}
产生错误的代码
Product b = new Product();
b.setId("ABC123");
b.setSize(Product.Size.LARGE);
Product c = new Product();
c.setId("DEF456");
c.setSize(Product.Size.XSMALL);
Order o = new Order();
o.setId(551234L);
o.setContactName("Marco");
o.addProduct(b);
o.addProduct(c);
System.out.println("Order ID=" + o);
堆栈跟踪
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.util.HashMap$KeyIterator.<init>(HashMap.java:1451)
at java.util.HashMap$KeySet.iterator(HashMap.java:912)
at java.util.HashSet.iterator(HashSet.java:172)
at java.util.AbstractCollection.toString(AbstractCollection.java:454)
at java.lang.String.valueOf(String.java:2979)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.code4armour.shippingtracker.ui.model.Order.toString(Order.java:207)
at java.lang.String.valueOf(String.java:2979)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.code4armour.shippingtracker.ui.model.Band.toString(Band.java:78)
at java.lang.String.valueOf(String.java:2979)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at java.lang.String.valueOf(String.java:2979)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.code4armour.shippingtracker.ui.model.Order.toString(Order.java:207)
at java.lang.String.valueOf(String.java:2979)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.code4armour.shippingtracker.ui.model.Band.toString(Band.java:78)
这里的问题是 Order.toString()
调用 Product.toString()
,反之亦然
The problem here is the Order.toString()
calling the Product.toString()
, and vice versa
推荐答案
您可能要考虑包含两个实例的管理类/对象.通过此操作,您可以分别安全地调用这两个 toString()
方法.
You may want to consider a managing class/object which contains instance(s) of both. Through this you could call both toString()
methods separately and safely.
编辑(从我的第一条评论继续):
Edit (continuing from my first comment):
Order_Product_Link(表)
Order_Product_Link (table)
- OrderID(FK)
- 产品ID(FK)
约束:-orderID和productID的组合应该是唯一的
Constraints:- the combination of orderID and productID should be unique
注意事项:
- 确保级联删除.因此,如果删除产品条目,则需要删除Order_Product_Link中所有引用其ID的条目.但是,您很可能不希望删除订单.反之亦然.
这篇关于休眠实体循环引用产生StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!