0

Right now I have

@Entity
public class Argument extends Model
{
    @Id
    public Long id;

    @Required @NotEmpty @Size(max = 140)
    public String summary;

    @SuppressWarnings("unchecked")
    public static Finder<Long, Argument> find = new Finder(Long.class, Argument.class);
    ...
}

and

@Entity
public class Relation extends Model
{
    @Id
    public Long id;

    @Required @ManyToOne @NotNull @JsonManagedReference
    public Argument from;
    @ManyToOne @JsonManagedReference
    public Argument toArgument;
    @ManyToOne @JsonManagedReference
    public Relation toRelation;
    @Required @NotNull
    public Integer type;
    ...
}

Basically, a Relation links two arguments (or an argument and another relation) together. It's a one-direction relationship between the two classes. And yet I get

[RuntimeException: java.lang.IllegalArgumentException: Infinite recursion 
(StackOverflowError) (through reference chain: models.Argument["relations"]-> 
com.avaje.ebean.common.BeanList[0]->models.Relation["from"]-> 
models.Argument["relations"]-> ... ->models.Argument["relations"])
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:611) ~[jackson-databind.jar:2.2.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142) ~[jackson-databind.jar:2.2.2]
    ...

when I try to do

find.where().or(Expr.eq("from", argument), Expr.eq("toArgument", argument)).findList();

and later call Json.toJson on that result.

Adding @JsonBackReference to the fields that reference Argument solves the problem by leaving out those fields entirely, which is not what I want. Adding @JsonManagedReference keeps the problem unchanged because I don't see anywhere to add the @JsonBackReference -- it's a one-direction relationship, darn it!

Basically, all I want is a JSON array of relations involving a certain argument. The JSON objects representing the relations should only contain IDs -- something like {id: 1, from: 4, toArgument: 3, type: 1} would be exactly what I want.

EDIT I should add that views that previously worked fine with the Argument model are now encountering the same error when the request is in JSON -- despite working solely with Arguments! Why would something in a completely different class affect Argument when I'm not even changing Argument at all?

wrongusername
  • 18,564
  • 40
  • 130
  • 214

1 Answers1

5

Solved it finally with this and this answer. I had to add

@OneToMany(fetch = FetchType.LAZY, mappedBy = "from") @JsonBackReference
public List<Relation> fromThis;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "toArgument") @JsonBackReference
public List<Relation> toThis;

to Argument.

Don't totally understand why, and now I get the entire Argument object embedded in the JSON -- instead of only the ID, which was what I wanted. Oh well, I guess.

Community
  • 1
  • 1
wrongusername
  • 18,564
  • 40
  • 130
  • 214