如何正确映射@OneToMany 和@ManyToOne 关系,以便我可以保存和更新@OneToMany 端(有或没有@ManyToOne 端)
Posted
技术标签:
【中文标题】如何正确映射@OneToMany 和@ManyToOne 关系,以便我可以保存和更新@OneToMany 端(有或没有@ManyToOne 端)【英文标题】:How do I map an @OneToMany and @ManyToOne relationship properly so that I can save and update the @OneToMany side with or without the @ManyToOne side 【发布时间】:2020-11-03 01:05:56 【问题描述】:我有一个带有 Angular 前端和 Spring 后端的应用程序。这里有问题的两个类是(后端):
@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<>();
和
@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;
当我保存和/或更新 TournamentGame
对象时,我需要帮助弄清楚如何持久化 List<TournamentGamesPlayers>
。我生成了 45 个游戏。前 30 场比赛都有已知玩家,所以我在保存之前设置了它们。最后 15 个没有 TournamentGamesPlayers
连接表的条目,因为我需要稍后添加它们。
当我最初生成游戏时,我能够在@OneToMany
端使用CascadeType.ALL
获得一些结果,但是当我尝试更新具有看似无限递归/堆栈溢出的游戏时它失败了。
如果我省略任何级联类型,则会生成游戏端,但不会输入连接表 @ManyToOne
端。
【问题讨论】:
你能澄清你的问题吗? 我想我的问题是处理上面定义的这种关系的最佳方法是什么。我有一个包含 TournamentGamesPlayers 列表的 TournamentGame。 TournamentGamesPlayers 映射到一个包含 TournamentGame 和 Player 的复合键的连接表,并添加了一个附加字段。现在的问题似乎是我可以更新一个 TournamentGame,只要它在连接表中有现有的 TournamentGamesPlayers 条目......但是如果我有一个在连接表中没有此类条目的游戏,并希望通过将新 List尝试将 CascadeType.MERGE、CascadeType.ALL “删除父项和孤儿” (JPA CascadeType.ALL does not delete orphans)。
此外,将关系定义为 EAGER 并且不忽略 JSON 属性可能会出现问题。我会将@JsonIgnore 添加到关系的一部分中
【讨论】:
【参考方案2】:我最终只是将玩家放回游戏桌以让我的生活更轻松。
【讨论】:
以上是关于如何正确映射@OneToMany 和@ManyToOne 关系,以便我可以保存和更新@OneToMany 端(有或没有@ManyToOne 端)的主要内容,如果未能解决你的问题,请参考以下文章
在 Scala Play 框架中映射 OneToMany 不向第二个表插入数据
如何使用 HQL 在 OneToMany 映射中查找列的最大值?
如何在 Hibernate 中创建 OneToMany 映射? [复制]