spring-boot - Spring Data JPA 可以通过@JoinColumn 强制执行多对一关系吗
问题描述
我有一个使用 Spring Data REST 和 Spring Data JPA 的 Spring Boot 应用程序。我有两个域实体:学生和教室,其中许多学生可以属于同一个教室。
学生:
@Data
@Entity
@Table(name = "STUDENT")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "STUDENT_ID")
private Integer studentId; // This Id has been setup as auto generated in DB
@Column(name = "ROOM_ID")
private Integer roomId;
@ManyToOne
@JoinColumn(name = "ROOM_ID", nullable = false, updatable = false, insertable = false)
private Classroom classroom;
}
课堂:
@Data
@Entity
@Table(name = "CLASSROOM")
public class Classroom {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROOM_ID")
private Integer roomId; // This Id has been setup as auto generated in DB
@OneToMany(mappedBy = "classroom")
private List<Student> studentList;
.....// other fields related to a classroom
}
和学生存储库:
public interface StudentRepository extends CrudRepository<Student , Integer>{
List<Student> findByClassroom(@Param("room") Classroom room);
}
和课堂存储库:
public interface ClassroomRepository extends CrudRepository<Classroom , Integer>{
}
我有一个 SpringApplication 主文件,但没有控制器。
CLASSROOM 表中已经有一个房间 id=1 的教室。当我向http://localhost:8080/students发出以下 POST 请求时,在 Student 表中创建了一个新的学生记录,我预计它会失败,因为没有 id=100 的教室存在于课堂。
所以我的问题是:Spring Data JPA 是否可以强制执行 manyToOne 关系,或者这个外键强制必须在数据库端完成(Student 表中的非空 ROOM_ID 列没有被我们的 DBA 定义为合法的外键考虑)。如果必须在数据库端完成,那么在实体文件中定义 manyToOne 关系有什么意义?
另外,我知道学生实体中有多余的教室字段,我只是不知道在学生实体中保留哪一个(roomId 或“教室”字段),因为当我创建一个学生时,我想在请求中仅提供教室的 roomId。谢谢!
{
"roomId": 100 // I expect this request to fail because no roomId=100 in the CLASSROOM table.
}
解决方案
在实体文件中定义 manyToOne 关系有什么意义
因为是一个允许您定义实体图的对象关系映射工具。
您当前正在传递roomId
which 在您的 Entity 中只是另一个字段,因此您需要将其删除。
@Entity
@Table(name = "STUDENT")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "STUDENT_ID")
private Integer studentId; // This Id has been setup as auto generated in DB
@ManyToOne
@JoinColumn(name = "ROOM_ID", nullable = false)
private Classroom classroom;
}
然后,在 Spring Data Rest 中,您通过传递被引用实体的 self 链接来定义关联。
然后,您的请求需要如下所示:
{
"classroom" : "http://localhost:8080/classrooms/1"
}
在发布新记录时也删除 ID,并且正如您所注意到的,ID 是在数据库中自动生成的。
也可以看看:
推荐阅读
- java - 如何在嵌套地图中使用我的 Jackson KeyDeserializer?
- java - 使用 Spring Security 实现 UserDetail 和 UserDetailService 的自定义用户、角色、权限
- logging - 其他用户执行时如何查看 Google Web App 的日志记录?
- php - 根据元素之间的条件从 eloquent 查询中删除元素
- angular - How can we change angular-in-memory-web base url
- python - 使用显式索引写入 s[::-1]
- python-3.x - Selenium doesn't get necessary cookie
- php - LARAVEL - Edit function in tab view
- reactjs - type a React component in typescript
- android - Can't download documentation for android