1

我試圖實現三個表(the beginning of the problem with mappingJPA的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

,我設置productpropertyProductProperty中,並且在ProductProperty中加入收集雙向。

我可以犯錯嗎?

+0

不相關,但可以刪除嵌入ID中的NotNull和Column註釋。由於關係映射被標記爲MapsId,所以該字段通過關係來定義,並且這些註釋僅混淆事物。那可以是空的,因爲你永遠不會直接設置它 - JPA稍後會做。 – Chris

+0

@Chris就像你說的那樣,我刪除了所有註釋,但這並不能解決問題。我嘗試設置-Xss10m(用於測試無限循環),並且一切正常。所以在填充實體的算法中沒有問題。只保留'註釋'或'堆棧大小' –

+0

看起來你的對象模型的複雜性或深度只是難以在JVM的堆棧限制內進行遍歷。實際上,每個實體似乎都可以從其他實體中獲得,當遞歸遍歷時會導致問題嘗試增加-Xss設置。您也可能會減少互連性,例如刪除OneToMany映射之一併直接查詢它,而不是將其存儲在產品或屬性映射中。 – Chris

回答

1

看起來像您的對象模型的複雜性或深度只是難以在JVM的堆棧限制內進行遍歷。實際上,每個實體似乎都可以從其他實體訪問,這在遞歸遍歷時會導致問題。嘗試增加-Xss設置。您也可能會減少互連性,例如刪除OneToMany映射之一併直接查詢它,而不是將其存儲在產品或屬性映射中。您也可以使用EclipseLink提交增強功能,以便使用堆棧而不是遞歸遍歷對象圖形。

+0

我從另一面看問題,並決定我真的需要其他關係。事實上,我不需要存儲'屬性'OneToMany關係(如果需要我可以使用查詢),並且我不'產品'OneToMany關係到'productProperty',但我需要'product' OneToMany關係'propertyProperty'通過'property'。下一步 - 實現它並檢查StackOverflowError –

相關問題