【问题标题】:EntityManager.remove() does not generate delete query and does not remove entityEntityManager.remove() 不生成删除查询也不删除实体
【发布时间】:2017-11-10 19:04:33
【问题描述】:

我有以下表格:BOOK、AUTHOR 和 AUTHOR_BOOK。 AUTHOR_BOOK 用于引用书籍和作者之间的多对多关系,它包含两个字段:author_id 和 book_id。

所以在我的测试程序中,我首先添加了一本新书,新作者都不在数据库中,然后用我的Service实现查询新书,返回的Book对象是正确的,但是当我试图通过时它进入我的服务中的 deleteBook() 方法,这本书没有被删除,并且日志中没有生成删除 SQL。我的日志中也没有任何错误或异常,所以我不知道出了什么问题:(

这是类文件(仅发布我认为相关的部分)

@Entity
@Table(name = "book")
@NamedQueries({
        @NamedQuery(
                name = "Book.findAllWithDetails",
                query = "select distinct b from Book b left join fetch b.authors a left join fetch b.category c"
        ),
        @NamedQuery(
                name = "Book.findBookById",
                query = "select distinct b from Book b left join fetch b.authors a left join fetch b.category c where b.id = :id"
        )
})
@SqlResultSetMapping(
        name = "bookResult",
        entities = @EntityResult(entityClass = Book.class)
)
public class Book {
    private Long id;
    private String isbn;
    private String title;
    private Float price;
    private Category category;
    private Set<Author> authors = new HashSet<>();

    public Book() { }

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "author_book",
               joinColumns = @JoinColumn(name = "book_id"),
               inverseJoinColumns = @JoinColumn(name = "author_id"))
    public Set<Author> getAuthors() {
        return authors;
    }

    public void setAuthors(Set<Author> authors) {
        this.authors = authors;
    }

    public void addAuthor(Author author) {
        authors.add(author);
        //author.addBook(this);
    }

    public void removeAuthor(Author author) {
        authors.remove(author);
        //author.removeBook(this);
    }
}

@Entity
@Table(name = "author")
public class Author {
    private Long id;
    private String firstName;
    private String lastName;
    private String description;
    private Set<Book> books = new HashSet<>();

    public Author() { }

    @ManyToMany
    @JoinTable(name = "author_book",
               joinColumns = @JoinColumn(name = "author_id"),
               inverseJoinColumns = @JoinColumn(name = "book_id"))
    public Set<Book> getBooks() {
        return books;
    }

    public void setBooks(Set<Book> books) {
        this.books = books;
    }

//    public void addBook(Book book) {
//        getBooks().add(book);
//    }
//
    public void removeBook(Book book) {
        getBooks().remove(book);
    }
}

Service("jpaPublishingService")
@Repository
@Transactional
public class PublishingServiceImpl implements PublishingService {
    private final String ALL_BOOK_NATIVE_QUERY = "select id, title, isbn, price, category_id from book";
    private static Logger logger = LoggerFactory.getLogger(PublishingServiceImpl.class);

    @PersistenceContext
    private EntityManager em;

    // use namedQuery
    @Override
    @Transactional(readOnly = true)
    public List<Book> findAllBooksWithDetails() {
        return em.createNamedQuery("Book.findAllWithDetails", Book.class).getResultList();
    }

    // use namedQuery
    @Override
    @Transactional(readOnly = true)
    public Book findBookByIdWithDetails(Long id) {
        TypedQuery<Book> query = em.createNamedQuery("Book.findBookById", Book.class);
        query.setParameter("id", id);
        return query.getSingleResult();
    }

    // save using JPA2
    @Override
    public Book createNewBook(Book book) {
        if (book.getId() == null) {
            logger.info("Inserting new book");
            em.persist(book);
        } else {
            em.merge(book);
            logger.info("Updating existing book");
        }
        logger.info("Book saved with id: " + book.getId());
        return book;
    }

    // delete using JPA2
    @Override
    public void deleteBook(Book book) {
        Book mergedBook = em.merge(book);
        em.remove(mergedBook);
        logger.info("Book with id: " + mergedBook.getId()  + " deleted successfully");
    }
}

如果还需要什么,请告诉我。感谢您的帮助!

【问题讨论】:

    标签: java mysql spring jpa


    【解决方案1】:

    尝试删除 book 对象而不合并它(使用 em.find),它对我有用。

    public void deleteBook(Book book) {
            // Book mergedBook = em.merge(book);
            Book b1=em.find(Book.class,book.getId);
            em.remove(b1);
            logger.info("Book with id: " + mergedBook.getId()  + " deleted successfully");
        }
    

    【讨论】:

    • 我试过但它输出错误“java.lang.IllegalArgumentException: Removing a detached instance com.yzhan.bookapp.domain.Book”
    • 真的很抱歉,我忘记了 em.find
    猜你喜欢
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多