Infinite recursion (StackOverflowError)

3,122 views
Skip to first unread message

moebius

unread,
Nov 18, 2013, 5:16:47 AM11/18/13
to light...@googlegroups.com
Hi,

I am suffering from the following exception when editing an entity:

Infinite recursion (StackOverflowError) (through reference chain: org.springframework.data.rest.webmvc.EntityResource["[anySetter]"]->java.util.LinkedHashMap["addressByAddressCustomerId"]->java.util.LinkedHashMap["value"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->org.springframework.hateoas.Resource["content"]->...

I understand that this is based on the one2many relationships with embedded entities, that refer back to other entities in a cyclic way.
I googled this and found similar problems, e.g. here: http://stackoverflow.com/questions/10191671/jackson-json-serialization-recursion-avoidance-by-level-defining

Is there any way to limit the depth of these recursions?

Thanks a lot for a swift response!

Irina Kostenko

unread,
Nov 18, 2013, 4:56:35 PM11/18/13
to light...@googlegroups.com
Hi moebius,

Thank you for being helpful for others in this group :)
Could you please provide sources of affected entities and their administration classes so that we can investigate the issue?

Best regards,
Iryna Kostenko

moebius

unread,
Nov 29, 2013, 4:40:16 AM11/29/13
to light...@googlegroups.com
Dear Iryna,

sorry for the delay.

These are two of the entities that I generated with HibernateTools/hbm2java (i have shortened the code a bit).
I am aware that the sets referring to the "parent" entity may not be best practice.

@Entity
@Table(name = "ORDER")
public class Order implements java.io.Serializable {

   
private static final long serialVersionUID = 1L;
   
private Long id;
   
private Location location;
   
   
public Order() {
   
}

   
@SequenceGenerator(name = "OrderSequence", sequenceName = "ORDER_SEQ", allocationSize = 1)
   
@Id
   
@GeneratedValue(strategy = SEQUENCE, generator = "OrderSequence")
   
@Column(name = "ID", unique = true, nullable = false, precision = 9, scale = 0)
   
public Long getId() {
       
return this.id;
   
}

   
public void setId(Long id) {
       
this.id = id;
   
}

   
@ManyToOne(fetch = FetchType.LAZY)
   
@JoinColumn(name = "LOCATION_ID", nullable = false)
   
public Location getLocation() {
       
return this.location;
   
}

   
public void setLocation(Location location) {
       
this.location = location;
   
}
}


@Entity
@Table(name="LOCATION"
)
public class Location  implements java.io.Serializable {

     
private String id;
     
private String description;
     
private Set<Order> orders = new HashSet<Order>(0);

   
@Id
   
@Column(name="ID", unique=true, nullable=false, length=64)
   
public String getId() {
       
return this.id;
   
}
   
   
public void setId(String id) {
       
this.id = id;
   
}
   
   
@Column(name="DESCRIPTION", nullable=false, length=64)
   
public String getDescription() {
       
return this.description;
   
}
   
   
public void setDescription(String description) {
       
this.description = description;
   
}
   
   
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="location")
   
public Set<Order> getOrders() {
       
return this.orders;
   
}
   
   
public void setOrders(Set<Order> orders) {
       
this.orders = orders;
   
}
}


The problem is this: the order entity has a foreign key to the location entity.
Hbm2java therefore generates a Location field in the Order entity, but also a Set<Order> in the Location entity.

When lightadmin now generates the RESTful service, it tries to deliver the complete data in a recursive way.
Order > Location > Orders > Location > ...

I see a few possible solutions to this:
- I remove the set from the location entity (easiest, but might depend on the modelling)
- The lazy loading would be taken into consideration when grabbing the data and preparing the JSON array
- There are spring data annotations for limiting/managing the depth of the recursion, maybe they could be activated: @JsonManagedReference and @JsonBackReference

What is your opinion on this?

Thanks a lot!





moebius

unread,
Nov 29, 2013, 4:45:12 AM11/29/13
to light...@googlegroups.com

Irina Kostenko

unread,
Dec 13, 2013, 8:07:12 AM12/13/13
to light...@googlegroups.com
Hi moebius,

The problem you encounter is reproducible when @ManyToOne annotation has fetch = FetchType.LAZY
A bug has been submitted about this - https://github.com/max-dev/light-admin/issues/105

Until the bug is fixed, you can use workaround: remove fetch = FetchType.LAZY from @ManyToOne annotations in your entities.

Hope this is suitable for you.

Best regards,
Iryna Kostenko

Reply all
Reply to author
Forward
0 new messages