我試圖實現三個表(the beginning of the problem with mapping)JPA的StackOverflowError當關系表中加載數據
Products
加載:
@Entity
@Table(name = "products")
public class Product implements Serializable {
@Id
@Column(name = "id")
private Integer id;
@OneToMany(mappedBy = "property", fetch = FetchType.LAZY)
private Collection<ProductProperty> productPropertyCollection;
...
}
Properties
:
@Entity
@Table(name = "properties")
public class Property implements Serializable {
@Id
@Column(name = "id")
private Integer id;
@OneToMany(mappedBy = "property", fetch = FetchType.LAZY)
private Collection<ProductProperty> productPropertyCollection;
...
}
Product_Property
@Entity
@Table(name = "product_property")
public class ProductProperty implements Serializable {
@EmbeddedId
protected ProductPropertyPK productPropertyPK;
@MapsId(value = "propertyId")
@JoinColumn(name = "property_id", referencedColumnName = "id")
@ManyToOne()
private Property property;
@MapsId(value = "productId")
@JoinColumn(name = "product_id", referencedColumnName = "id")
@ManyToOne()
private Product product;
...
}
@Embeddable
public class ProductPropertyPK implements Serializable {
@Basic(optional = false)
@NotNull
@Column(name = "product_id", insertable = false, updatable = false)
private int productId;
@Basic(optional = false)
@NotNull
@Column(name = "property_id", insertable = false, updatable = false)
private int propertyId;
...
}
它工作正常的1,10,100個產品,但冥冥之中有一個錯誤,因爲1000多的產品會拋出錯誤:
Caused by: java.lang.StackOverflowError
at java.util.HashMap.getEntry(HashMap.java:443)
at java.util.HashMap.containsKey(HashMap.java:434)
at java.util.HashSet.contains(HashSet.java:201)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4141)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.CollectionMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(CollectionMapping.java:426)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.CollectionMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(CollectionMapping.java:426)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
...
當我創建ProductProperty
,我設置product
和property
在ProductProperty
中,並且在Product
和Property
中加入收集雙向。
我可以犯錯嗎?
不相關,但可以刪除嵌入ID中的NotNull和Column註釋。由於關係映射被標記爲MapsId,所以該字段通過關係來定義,並且這些註釋僅混淆事物。那可以是空的,因爲你永遠不會直接設置它 - JPA稍後會做。 – Chris
@Chris就像你說的那樣,我刪除了所有註釋,但這並不能解決問題。我嘗試設置-Xss10m(用於測試無限循環),並且一切正常。所以在填充實體的算法中沒有問題。只保留'註釋'或'堆棧大小' –
看起來你的對象模型的複雜性或深度只是難以在JVM的堆棧限制內進行遍歷。實際上,每個實體似乎都可以從其他實體中獲得,當遞歸遍歷時會導致問題嘗試增加-Xss設置。您也可能會減少互連性,例如刪除OneToMany映射之一併直接查詢它,而不是將其存儲在產品或屬性映射中。 – Chris