andrey.ladniy
andrey.ladniy

Reputation: 1674

JPA StackOverflowError when loading data in relationship tables

I'm trying to implement loading in three tables (the beginning of the problem with mapping)

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;
    ...
}

It works fine for 1, 10, 100 products, but somewhere there is an error, because for 1000 and more products throws error:

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)
...

when i'm creating ProductProperty, i'm setting product and property in ProductProperty, and adding to collection for bidirection in Product and Property.

where i could make a mistake?

Upvotes: 1

Views: 1225

Answers (1)

Chris
Chris

Reputation: 21165

Looks like your object model complexity or depth is just difficult to traverse within your JVM's stack limits. As it is, every entity seems reachable from every other entity, which causes problems when traversed recursively. Try increasing the -Xss setting. You might also reduce the interconnectivity, such as removing one of the OneToMany mappings and query for it directly instead of storing it in the Product or Property mapping. You might also file an enhancement with EclipseLink to traverse the object graph using a stack instead of recursively.

Upvotes: 1

Related Questions