避免无限递归(StackOverflowError)而不丢失JPA和Jackson JSON的信息

时间:2018-08-09 04:15:01

标签: java hibernate spring-boot jackson spring-data-jpa

我有3个班级:电影,演员和一个称为FilmActor的中级班。 因此,事实是,类FilmActor与Film和Actor具有ManyToOne关系,并且它们都与FilmActor类具有OneToMany关系,因为我想了解该演员的所有电影以及参与该电影的所有演员。

我尝试使用@JsonIgnore或@JsonManagedReference和@JsonBackReference,但是如果使用它们,我在寻找电影时会丢失演员的信息,而在寻找演员时会丢失电影的信息。

我想知道是否有办法可以获取所有信息并避免无限循环。

电影课:

@Entity
public class Film{

    private List<FilmActor> cast;

    @OneToMany(mappedBy="filmActorFilm")
    public List<FilmActor> getCast() {
        return cast;
    }

}

演员班:

@Entity
public class Actor{

    private List<FilmActor> credits;

    @OneToMany(mappedBy="filmActorActor")
    public List<FilmActor> getCredits() {
        return credits;
    }

}

FilmActor类:

@Entity
public class FilmActor{

    public Film filmActorFilm;
    public Actor filmActorActor;

    @ManyToOne(optional=false,fetch=FetchType.LAZY)
    @JoinColumn(name="filmActorFilm")
    public Film getFilmActorFilm() {
        return filmActorFilm;
    }

    @ManyToOne(optional=false,fetch=FetchType.LAZY)
    @JoinColumn(name="filmActorActor")
    public Actor getFilmActorActor() {
        return filmActorActor;
    }

}

修改

我认为一开始我还不够清楚。我正在尝试使用Spring Boot创建一个休息服务器,当我尝试获取电影的演员列表和演员的电影列表时,我的问题就来了。当我尝试获取Film时,应用程序获得的属性Cast是FilmActor的列表,如果我什么都不做,则将导致死循环,因为FilmActor类也具有Film类。

我可以在方法getFilmActorActor的getter上使用注释@JsonIgnore或在Film和FilmActor类的对应方法中同时使用注释@JsonManagedReference和@JsonBackReference来轻松避免这种情况。使用这些注释,我可以避免无限循环,因为当我获得影片时,应用程序会使用@JsonIgnore跳过该属性,在这种情况下,即涉及影片的filmActorFilm。问题是,如果我跳过此属性,则在搜索演员时不会获得该属性,而我唯一能知道的是该演员参与的电影数量,但我也想获取该电影的信息。为此,我必须取消Json注释。试图让所有参加电影的演员都面临相反的问题。

所以,我要寻找的是一种仅在获得电影后才跳过属性filmActorFilm,而在获得演员后就跳过属性filmActorActor的方法。

2 个答案:

答案 0 :(得分:0)

您可能可以查看有关相应问题的两个答案(早前在StackOverflow上已回答)。 Question1Question2。您肯定会深入了解如何有效地在休眠状态下使用这些注释(@OneToMany@ManyToOne@JoinColumn等),以便获得最佳结果。

答案 1 :(得分:0)

我和你有同样的问题。就我而言,我有sourceBatch和childBatch而不是Actor和Film,并且必须@JsonIgnore我的childBatch。

这是我的解决方法,

-为您的实体类(以及其getter和setter)中忽略的值创建一个瞬态字段,

@Transient
@JsonProperty('tempChildBatches')
private Collection<Batch> tempChildBatches = new ArrayList<>();

-在@Controller类方法中,该方法将数据传递到前端,

Collection<Batch> tempHolder = batch.getChildBatches(); //Original JsonIgnored field getter method
batch.setTempChildBatches(tempHolder); //Setter for the transient field

现在,您的前端应该可以通过此临时字段接收@JsonIgnore数据。希望对您有所帮助。