Java 如何从JPA中的联接表中删除数据
我试图创建一个图书馆管理系统,因为我创建了两个实体Java 如何从JPA中的联接表中删除数据,java,mysql,spring-boot,hibernate,jpa,Java,Mysql,Spring Boot,Hibernate,Jpa,我试图创建一个图书馆管理系统,因为我创建了两个实体Student和Books都是使用@manytomy关系连接的,所以我使用了另一个联接表,当学生从图书馆发行图书时,但当学生返回包含联接表中两个ID的行的图书,但当我尝试删除联接表中的所有数据或删除我的学生和图书时 这是我的代码,请告诉我我做错了什么,最好的做法是什么 学生实体 package com.Library.LibraryManagement.Entity; import java.sql.Timestamp; import java
Student
和Books
都是使用@manytomy
关系连接的,所以我使用了另一个联接表,当学生从图书馆发行图书时,但当学生返回包含联接表中两个ID的行的图书,但当我尝试删除联接表中的所有数据或删除我的学生和图书时
这是我的代码,请告诉我我做错了什么,最好的做法是什么
学生实体
package com.Library.LibraryManagement.Entity;
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="student_email")
private String email;
@Column(name="student_course")
private Integer course;
@Column(name="date_of_birth")
private String dateOfBirth;
@Column(name="student_status")
private Integer status;
@Column(name="added_at")
private Timestamp addedAt;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name="student_books",
joinColumns=@JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name="books_id"))
private List<Books> books;
public Student() {
//Empty Constructor
}
public Student(String firstName, String lastName, String email, Integer course,String dateOfBirth,Integer status,Timestamp addedAt) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.course = course;
this.dateOfBirth = dateOfBirth;
this.status = status;
this.addedAt = addedAt;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getCourse() {
return course;
}
public void setCourse(Integer course) {
this.course = course;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Timestamp getAddedAt() {
return addedAt;
}
public void setAddedAt(Timestamp addedAt) {
this.addedAt = addedAt;
}
public List<Books> getBooks() {
return books;
}
public void setBooks(List<Books> books) {
this.books = books;
}
public void removeBook(Books boo) {
this.books.remove(boo);
boo.getStudents().remove(this);
}
@Override
public String toString() {
return "{\"id\":\"" + id + "\", \"firstName\":\"" + firstName + "\", \"lastName\":\"" + lastName
+ "\", \"email\":\"" + email + "\", \"course\":\"" + course + "\", \"dateOfBirth\":\"" + dateOfBirth
+ "\", \"status\":\"" + status + "\", \"addedAt\":\"" + addedAt + "\"}";
}
}
package com.Library.LibraryManagement.Entity;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="books")
public class Books {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="book_name")
private String bookName;
@Column(name="book_publisher")
private String bookPublisherName;
@Column(name="book_description")
private String bookDescription;
@Column(name="book_language")
private String bookLanguage;
@Column(name="book_in_stock")
private Integer bookInStock;
@Column(name="added_at")
private Timestamp addedAt;
@Column(name="deleted")
private Integer deleted;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name="student_books",
joinColumns=@JoinColumn(name = "books_id"),
inverseJoinColumns = @JoinColumn(name="student_id"))
private List<Student> students;
public Books() {
}
public Books(String bookName, String bookPublisherName, String bookDescription, String bookLanguage,Timestamp addedAt,
Integer bookInStock,Integer deleted) {
this.bookName = bookName;
this.bookPublisherName = bookPublisherName;
this.bookDescription = bookDescription;
this.bookLanguage = bookLanguage;
this.bookInStock = bookInStock;
this.addedAt =addedAt;
this.deleted = deleted;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookPublisherName() {
return bookPublisherName;
}
public void setBookPublisherName(String bookPublisherName) {
this.bookPublisherName = bookPublisherName;
}
public String getBookDescription() {
return bookDescription;
}
public void setBookDescription(String bookDescription) {
this.bookDescription = bookDescription;
}
public String getBookLanguage() {
return bookLanguage;
}
public void setBookLanguage(String bookLanguage) {
this.bookLanguage = bookLanguage;
}
public Integer getBookInStock() {
return bookInStock;
}
public void setBookInStock(Integer bookInStock) {
this.bookInStock = bookInStock;
}
public Timestamp getAddedAt() {
return addedAt;
}
public void setAddedAt(Timestamp addedAt) {
this.addedAt = addedAt;
}
public Integer getDeleted() {
return deleted;
}
public void setDeleted(Integer deleted) {
this.deleted = deleted;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public void removeBook(Student stu) {
this.students.remove(stu);
stu.getBooks().remove(this);
}
@Override
public String toString() {
return "{\"id\":\"" + id + "\", \"bookName\":\"" + bookName + "\", \"bookPublisherName\":\"" + bookPublisherName
+ "\", \"bookDescription\":\"" + bookDescription + "\", \"bookLanguage\":\"" + bookLanguage
+ "\", \"bookInStock\":\"" + bookInStock + "\", \"addedAt\":\"" + addedAt + "\", \"deleted\":\""
+ deleted + "\"}";
}
//Convience MEthods to help with adding the student
public void addStudent(Student theStudent) {
if(students ==null) {
students = new ArrayList<>();
}
students.add(theStudent);
}
}
应该是
student.getBooks().remove(book);
entityManger.save(student)
应该是
student.getBooks().remove(book);
entityManger.save(student)
这是因为您正在使用
entityManager.remove
。由于级联,该命令将删除一个学生以及与之关联的所有书籍
如果您只想从关联中删除一本书,那么returnBook
方法应该如下所示:
@Transactional
public void returnBook(Student student, Books book) {
try {
if(student !=null && book !=null) {
Student entityStudent = entityManager.getReference( Student.class, student.getId())
Book entityBook = entityManager.getReference( Book.class, book.getId())
entityStudent.removeBook(entityBook);
}
}
...
}
在提交或刷新会话期间,更改将传播到数据库
注意,我添加了getReference()
调用,因为我不知道student
和book
是否为托管实体。如果是,则无需使用getReference()
假设这就是removeBook
的样子:
public void removeBook(Book book) {
this.books.remove( book );
book.getStudents().remove( this );
}
如上所述,重要的是更新关联的双方
此外,其中一个实体上的关联映射应为:
@ManyToMany(mappedBy = "...")
您应该决定哪个实体拥有该关联
顺便问一下,您确定您试图实现的映射不是Hibernate ORM文档中描述的映射,如示例172所示。具有链接实体的双向多对多?这是因为您使用的是
entityManager。请删除。由于级联,该命令将删除一个学生以及与之关联的所有书籍
如果您只想从关联中删除一本书,那么returnBook
方法应该如下所示:
@Transactional
public void returnBook(Student student, Books book) {
try {
if(student !=null && book !=null) {
Student entityStudent = entityManager.getReference( Student.class, student.getId())
Book entityBook = entityManager.getReference( Book.class, book.getId())
entityStudent.removeBook(entityBook);
}
}
...
}
在提交或刷新会话期间,更改将传播到数据库
注意,我添加了getReference()
调用,因为我不知道student
和book
是否为托管实体。如果是,则无需使用getReference()
假设这就是removeBook
的样子:
public void removeBook(Book book) {
this.books.remove( book );
book.getStudents().remove( this );
}
如上所述,重要的是更新关联的双方
此外,其中一个实体上的关联映射应为:
@ManyToMany(mappedBy = "...")
您应该决定哪个实体拥有该关联
顺便问一下,您确定您试图实现的映射不是Hibernate ORM文档中描述的映射,如示例172所示。具有链接实体的双向多对多
?您的多对多关系映射不正确
他说:
每一个多对多协会都有两个方面,一个是所有者,一个是所有者
非拥有方,或相反方在上指定联接表
拥有方。如果关联是双向的,则任何一方都可以是双向的
指定为拥有方如果关系是双向的,
非拥有方必须使用多个
注释以指定所属对象的关系字段或属性
一边
(重点补充)
您的注释映射关系就像双方都拥有它一样,这是不正确的
选择拥有方后,可以通过更新拥有方上的“关系”字段并保存修改后的拥有实体来修改关系。你有其他的答案说明如何做到这一点。您可能还希望对非拥有方进行相应的更改,或者刷新非拥有方实体以使该方的关系字段同步。您的多对多关系映射不正确
他说:
每一个多对多协会都有两个方面,一个是所有者,一个是所有者
非拥有方,或相反方在上指定联接表
拥有方。如果关联是双向的,则任何一方都可以是双向的
指定为拥有方如果关系是双向的,
非拥有方必须使用多个
注释以指定所属对象的关系字段或属性
一边
(重点补充)
您的注释映射关系就像双方都拥有它一样,这是不正确的
选择拥有方后,可以通过更新拥有方上的“关系”字段并保存修改后的拥有实体来修改关系。你有其他的答案说明如何做到这一点。您可能还希望对非拥有方进行相应的更改,或刷新非拥有方实体以使该方的关系字段同步。不要使用returnBooke方法,请使用以下方法:
@Override
@Transactional
public void returnBok(Student student, Books book) {
try {
if (student != null && book != null) {
student.getBooks().removeIf(books -> {
return Objects.equals(book.getId(), books.getId());
});
entityManager.save(student);
}
} catch (Exception e) {
e.printStackTrace();
}
}
因为在上述方法中,您正在删除整个student对象entityManage.remove(student)代码>,这就是您的学生被删除并到期的原因
cascade=CascadeType。映射书对象中的所有
也将被删除
还有一个建议。而不是填充Getter、Setter和构造函数
使用Lombok插件:
不要使用您的返回方法,请使用以下方法:
@Override
@Transactional
public void returnBok(Student student, Books book) {
try {
if (student != null && book != null) {
student.getBooks().removeIf(books -> {
return Objects.equals(book.getId(), books.getId());
});
entityManager.save(student);
}
} catch (Exception e) {
e.printStackTrace();
}
}
因为在上述方法中,您正在删除整个student对象entityManage.remove(student)代码>,这就是您的学生被删除并到期的原因
cascade=CascadeType。映射书对象中的所有
也将被删除
还有一个建议。而不是填充Getter、Setter和构造函数
使用Lombok插件:
这是否回答了您的问题