当前位置: 首页 > 知识库问答 >
问题:

我应该如何从JPA中连接表中删除数据

郎刚捷
2023-03-14

我试图创建一个图书馆管理系统,因为我创建了两个实体studentbooks这两个实体都是使用@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();
        }
    }

共有1个答案

乜业
2023-03-14

这是因为您使用的是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()调用,因为我不知道studentbook是否是托管实体。如果是,则不必使用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