首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >单向一对多抛出Hibernate无法添加或更新子行:外键约束失败

单向一对多抛出Hibernate无法添加或更新子行:外键约束失败
EN

Stack Overflow用户
提问于 2018-06-02 05:06:07
回答 2查看 214关注 0票数 0

我有一个应用程序,教用户如何玩各种纸牌游戏。持久化的数据模型由一个与Hands具有单向一对多关系的TrainingSession组成。

编辑澄清一下,Hand不存在于TrainingSession的上下文之外(即,它们是在TrainingSession被创建/销毁时创建/销毁的)。遵循数据驱动设计的原则,TrainingSession被视为聚合根,因此使用单个spring-data CrudRepository (即,不为Hand创建存储库)

当我尝试使用外键保存外键时,我得到: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法添加或更新子行:外键约束失败(blackjack.hand,constraint FKrpuxac6b80xc7rc98vt1euc3n TrainingSession (id) REFERENCES training_session (tsid))

我的问题是通过CrudRepository实例的“保存(TrainingSession)”操作。我不明白的是,为什么错误消息会指出FOREIGN KEY (id) REFERENCES training_session (tsid))。这似乎是问题的原因,但我不明白为什么会这样,也不知道如何解决它。这种关系是单向的,并且Hand类中没有任何内容引用TrainingSession。

代码,减去所有的getter和setter,是:

代码语言:javascript
运行
复制
@Entity
public class TrainingSession {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer tsid;
private String strategy;

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="id")
private List<Hand> hands;

private int userId;

protected TrainingSession() {
}

public TrainingSession(int userId, Strategy strategy, List<Hand> hands) {
    this.strategy = strategy.getClass().getSimpleName();
    this.hands = hands;
    this.userId = userId;
}

Hand

代码语言:javascript
运行
复制
@Entity // This tells Hibernate to make a table out of this class
public class Hand {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private int p1;
private String p1s;
private int p2;
private String p2s;
private int d1;
private String d1s;
private int trials;
private int score;

public Hand() {
}
EN

回答 2

Stack Overflow用户

发布于 2018-06-02 05:41:01

在保存将Hand对象添加到TrainingSession之前,需要先保存TrainingSession和hand对象。

代码语言:javascript
运行
复制
TrainingSession ts1 = new TrainingSession();
trainingSessionManager.save(ts1);

Hand hand1 = new Hand();
handManager.save(hand1);

Hand hand2 = new Hand();
handManager.save(hand2);

ts1.gethands().add(hand1);
ts1.gethands().add(hand2)

trainingSessionManager.save(ts1);

如果你检查你的数据库,你会发现3个表TrainingSession, Hand and TrainingSession_HandTrainingSession_Hand表同时引用了TrainingSession和Hand both。因此,在保存关系之前,您需要保存TrainingSession和hand。

票数 0
EN

Stack Overflow用户

发布于 2018-06-06 02:30:55

找到了问题所在。我假设当spring-data设置DB表时,它能够确定并设置单向的一对多关系。显然情况并非如此。当我将关系配置为双向时,一切似乎都正常。

要修复问题,请执行以下操作:

  • TrainingSession中删除了hands
  • Hands中的@joincolumn注释我添加了一个带有@ManyToOne注释的TrainingSession字段:

@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "tsid",nullable = false) @OnDelete(action = OnDeleteAction.CASCADE)私有TrainingSession tsession;

  • 我还在Hand类中添加了用于tsid的getter/setter

我现在可以只使用一个TrainingSessionRepository来保存整个聚合结构。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50650991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档