我试图创建一个图书馆管理系统,因为我创建了两个实体student
和books
这两个实体都是使用@manytomany
关系连接的,所以我使用了另一个联接表,在这里我存储了图书的Id和学生的Id,当学生从图书馆发出一本书时,但是当学生返回书时,联接表中包含这两个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);
}
}
用于从联接表中修改数据的方法
@Override
@Transactional
public void returnBok(Student student, Books book) {
try {
if(student !=null && book !=null) {
// Student stu = book.getStudents(.);
// book.removeBook(student);
for(Books books : student.getBooks()) {
student.removeBook(book);
}
entityManage.remove(student);
}
}catch(Exception e) {
e.printStackTrace();
}
}
这是因为您使用的是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);
}
}
...
}
更改将在提交或刷新会话期间传播到db。
注意,我添加了getReference()
调用,因为我不知道student
和book
是否是托管实体。如果是,则不必使用getReference()
。
假设这就是removebook
的样子:
public void removeBook(Book book) {
this.books.remove( book );
book.getStudents().remove( this );
}
正如Hibernate ORM文档中所描述的,更新关联的两个方面是很重要的。
此外,关联在其中一个实体上的映射应该是:
@ManyToMany(mappedBy = "...")
您应该决定哪个实体拥有关联。
顺便问一下,您确定您试图实现的映射不是Hibernate ORM文档中示例172中描述的映射。带链接实体的双向多对多
?
我想从两个表中删除相关的行。可能有外键,也可能没有。因此,可以肯定的是,我不想依赖外键及其在DELETE上的
问题内容: 假设我们有两个实体,A和B。B与A具有多对一关系,如下所示: 现在,我要删除对象,并将删除操作级联到其所有子项。有两种方法可以做到这一点: 添加到OneToMany批注中,让JPA删除所有子项,然后再从数据库中删除A对象。 保持类不变,只需让数据库级联删除操作即可。 使用后面的选项有什么问题吗?这会导致实体管理器保留对已删除对象的引用吗?我之所以选择选项2而不是选项1的原因是,选项1生
问题内容: 我想从表中删除约束。我的查询是: 但我得到一个错误: -您的SQL语法有误;检查与您的MySQL服务器版本相对应的手册,以在第1行的’constraint ‘ 附近使用正确的语法 问题答案: Mysql具有用于删除外键约束的特殊语法:
我想从表中删除约束。我的疑问是: 但我有一个错误: -您的SQL语法中有错误;查看与您的MySQL server版本相对应的手册,以了解在第1行“constraint”附近使用的正确语法
问题内容: 我有一个Delphi应用程序,其中显示了像这样的查询已玩过的游戏的列表: 当我单击DBNavigator中的删除按钮时,也会删除game_types表中的联接记录。这是一个问题,因为许多其他游戏可以是同一类型。 我需要做些什么才能删除游戏,而不删除游戏类型? 问题答案: 您需要使用“唯一表”动态属性 从MSDN ADO文档 如果设置了“唯一表”动态属性,并且Recordset是对多个表
问题内容: 我目前正在使用Hibernate Envers。 如何删除审核表中与我要删除的实体相关的条目?我的实体与其他实体没有任何关系。 我发现必须在自定义侦听器的方法中执行此操作: 我已经阅读了文档,论坛以及许多内容,但我无法弄清楚。也许这是不可能的,我不知道。 有人做过吗? 问题答案: 好吧,对于那些想知道的人,我已经完成了50%。 感谢Hibernate Envers的创建者Adam Wa