我有一个应用程序,教用户如何玩各种纸牌游戏。持久化的数据模型由一个与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,是:
@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是
@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() {
}发布于 2018-06-02 05:41:01
在保存将Hand对象添加到TrainingSession之前,需要先保存TrainingSession和hand对象。
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_Hand,TrainingSession_Hand表同时引用了TrainingSession和Hand both。因此,在保存关系之前,您需要保存TrainingSession和hand。
发布于 2018-06-06 02:30:55
找到了问题所在。我假设当spring-data设置DB表时,它能够确定并设置单向的一对多关系。显然情况并非如此。当我将关系配置为双向时,一切似乎都正常。
要修复问题,请执行以下操作:
TrainingSession中删除了handsHands中的@joincolumn注释我添加了一个带有@ManyToOne注释的TrainingSession字段:@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "tsid",nullable = false) @OnDelete(action = OnDeleteAction.CASCADE)私有TrainingSession tsession;
我现在可以只使用一个TrainingSessionRepository来保存整个聚合结构。
https://stackoverflow.com/questions/50650991
复制相似问题