0

I have an app with Angular front end and Spring backend. The two classes in question here are (backend):

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tournament_games")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class TournamentGame {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "code", foreignKey = @ForeignKey(name = "code_fk"))
    private TournamentCode code;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "type", foreignKey = @ForeignKey(name = "game_type_fk"))
    private GameType type;

    @Column(name = "home_score")
    private int home_score;

    @Column(name = "away_score")
    private int away_score;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "result_type", foreignKey = @ForeignKey(name = "result_type_fk"))
    private ResultType result_type;

    @Column(name = "status")
    private boolean status;

    @Column(name = "round")
    private int round;

    @Column(name = "locked")
    private boolean locked;

    @OneToMany(mappedBy = "game", fetch = FetchType.EAGER)
    private List<TournamentGamesPlayers> players = new ArrayList<>();
}

and

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tournament_games_players")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "game")
public class TournamentGamesPlayers implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @ManyToOne
    @JoinColumn(name = "tournament_game_id")
    private TournamentGame game;

    @Id
    @ManyToOne
    @JoinColumn(name = "playerid")
    private Player player;

    @Column(name = "home")
    private boolean home;
}

I need help figuring out how to persist the List<TournamentGamesPlayers> when I save and/or update a TournamentGame object. I generate 45 games. The first 30 games have known players, and so I set them before saving. The last 15 do not have entries for the TournamentGamesPlayers join table, because I need to add them later.

I am able to get some results with CascadeType.ALL on the @OneToMany side when I initially generate the games, but it fails when I try to update a game with a seemingly infinite recursion/stack overflow.

If I omit any cascade type, the games side get generated, but the join table @ManyToOne side does not get entered.

cyberguy
  • 233
  • 3
  • 10
  • Can you clarify your question? – Woodchuck Jul 13 '20 at 21:24
  • I guess my question is what's the best way to handle this relationship defined above. I have a TournamentGame which contains a list of TournamentGamesPlayers. The TournamentGamesPlayers map to a join table with a composite key of TournamentGame and Player, with an additional field thrown in. The problem now seems to be that I can update a TournamentGame provided it has existing TournamentGamesPlayers entries in the join table... but if I have a game with no such entries in the join table, and wish to add them by adding a new List to the property, and saving it, I can't – cyberguy Jul 13 '20 at 21:45
  • Removing cascading all together allows me to update an existing game without a stack overflow. However, it doesn't seem to save new entries in the join table (aka the new TournamentGamesPlayers)... it throws an error unable to find TournamentGamesPlayers with id... I generate 45 games. 30 of those the players are known from the start. The last 15 games do not have entries in the join table yet. I would like to persist those later by setting the List and saving the TournamentGame. Not sure how to do that. – cyberguy Jul 13 '20 at 21:49
  • In fact, now that I have removed cascading, my initial 30 games don't save entries to my join table anymore. I just ran a new tournament. 45 games get added to the database with their default values. But the List which I assigned to the first 30 games don't get persisted. – cyberguy Jul 13 '20 at 21:58
  • 1
    I updated the question with some clarification and with my updated code. – cyberguy Jul 13 '20 at 22:06

2 Answers2

0

I ended up just putting the players back into the game table to make my life easier.

cyberguy
  • 233
  • 3
  • 10
0

try putting CascadeType.MERGE, CascadeType.ALL "delete parent and orphans" (JPA CascadeType.ALL does not delete orphans).

Also, defining the relationship as EAGER and not ignoring the JSON property can have problems. I would add @JsonIgnore to one of the parts of the relationship

JLazar0
  • 1,257
  • 1
  • 11
  • 22