【问题标题】:Spring JPA stop creating a new table with relationshipSpring JPA 停止创建具有关系的新表
【发布时间】:2021-06-06 12:00:31
【问题描述】:

我正试图阻止我制作新表格的关系。我已经尝试了多种方法来解决这个问题,但每次我转向似乎都有一个错误。例如,当我尝试以下代码时:

//other variables
@OneToMany(fetch = FetchType.LAZY ,cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private List<User> users= new ArrayList<>();

我收到以下错误:

Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`eb322`.`#sql-3140_2e7`, CONSTRAINT `FK20sqpkpotyyf5wx4jfmp519lu` FOREIGN KEY (`user_id`) REFERENCES `year` (`year_id`))

我检查了数据库中的所有表和索引,但在任何地方都找不到这个约束。我该如何删除它。我基本上希望我的架构是这样的:

  • 今年将有一个所有学生、教师的列表。当学生注册时,他们将被添加到该年等。

如果我不添加连接列,我只会得到另一个表说

  • Year.students

如何将这些组合在一起。

这是我的学生班,以防万一这里有问题:

public class Student{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int User_id;
}

我如何向年表添加数据

//get data about student
Student s = ssrepo.findByName(name);
Year y = yyrepo.findByYear(year);
List<Student> students = y.getStudents();
students.add(s);
yyrepo.save(y)

【问题讨论】:

  • 您能分享一下您是如何尝试将数据添加到年表的
  • 我会用答案修改问题

标签: java sql spring jpa relationship


【解决方案1】:

您似乎在使用单向 OneToMany 关系

Hibernate 使用关联表来映射关系,因此当您删除 @JoinColumn 注释时,会创建关联表。

由于 Year 与 student 是一对多的关系,所以 List 的类型应该是 List&lt;Student&gt; 而不是 List&lt;User&gt;

@OneToMany(fetch = FetchType.LAZY ,cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private List<Student> users= new ArrayList<>();

由于性能问题,通常不建议使用 OneToMany 单向关联。您可以考虑使用双向关联。应该是这样的

public class Year {

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

@Column(name = "TYPE_ID")
private Long typeId

@Column(name = "TYPE")
private Boolean type // 1 or 0 to know if typeId is of student or teacher

@Column(name = "YEAR")
private Date year


@OneToMany(mappedBy="typeId", fetch = FetchType.LAZY ,cascade = CascadeType.ALL)
private List<Student> students;

@OneToMany(mappedBy="typeId", fetch = FetchType.LAZY ,cascade = CascadeType.ALL)
private List<Teacher> teachers;

}

public class Teacher{

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

@ManyToOne
@JoinColumn(name="TYPE_ID", nullable=false)
 private Year typeId;

}

public class Student{

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

@ManyToOne
@JoinColumn(name="TYPE_ID", nullable=false)
 private Year typeId;

}

【讨论】:

  • 谢谢你,我会试试的!这是否允许我将同一个学生添加到多年?例如,它将是 2019-2020 年而不是 8 年?
  • 是的。这应该。我还没有测试过这段代码,所以如果你遇到任何问题。告诉我
  • Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (eb322.#sql-3140_59a, CONSTRAINT FKsrji3x3snoiiq1s2xei5lon2w`外键(type_id)参考student(`我得到这个错误,@98765)检查了学生和年份限制,我找不到它,知道如何删除这个限制吗?
  • List 和 List 引用对同一列施加了约束。但是外键约束必须只引用一个表。您可以删除此约束,它应该可以工作。如果你真的需要这个 fk 约束,你将需要更改数据库设计,并且可能需要添加一个新表。
【解决方案2】:

有两种方法可以做到这一点。第一个是双向的。在两个实体中进行映射的位置。在此链接中。(https://dzone.com/articles/introduction-to-spring-data-jpa-part-4-bidirection) 有例子。

public class MyClass {
    
        @OneToMany(mappedBy = "myClass", fetch = FetchType.LAZY, 
         cascade = CascadeType.ALL, orphanRemoval = true)
        @JoinColumn(name = "user_id")
        private List<User> users;
}

mappedBy 是说谁是关系中的主导者。在这种情况下,MyClass 的关系最强。

public class Student{
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private int id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private MyClass myClass;
}

我相信这是最好的方法,因为她的现实在两个实体中都很明显。有一种方法可以单向进行。链接中的示例 (How to define unidirectional OneToMany relationship in JPA)

【讨论】:

    猜你喜欢
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多