我在尝试StackOverflowError
引用Order
和引用Product
的{{1}}时获得Product
。我知道这是由于有一个循环引用,但我不确定如何解决它。我是ORM的新手,但不是SQL / Schema Design的新手:通常,我会有Order
表将Ordered_Products
映射到Order
,但我认为Hibernate会自动关注对我而言。
Product
都有唯一的ID(这些ID是在应用程序外部生成的),因此没有两个Product
是相同的。 Product
ID也会在应用程序外部生成(我将在此管道中的早期流程中从CSV导入此数据)。
有人可以协助前进吗?
Order
@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 */
}
}
@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()
,反之亦然
答案 0 :(得分:2)
这里的问题是调用Product.toString()的Order.toString(),反之亦然
您已经确定了问题,很清楚为什么要获得StackOverflowError
。只是不要从另一个实体的toString()
调用一个实体toString()
。
答案 1 :(得分:1)
您可能需要考虑包含两者实例的管理类/对象。通过这个,您可以单独安全地调用两个toString()
方法。
修改(从我的第一条评论继续):
Order_Product_Link(table)
约束: - orderID和productID的组合应该是唯一的
考虑: