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

Hibernate OnDelete级联测试不起作用

栾瑞
2023-03-14

我有单向相关实体:

@Entity
public class Book {
    private String isbn;
}

@Entity
private class Recommentation {
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "book_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Book book;
}

以及以下测试:

@RunWith(SpringRunner.class)
@DataJpaTest
public class BookRepositoryTest {

    @Autowired
    private TestEntityManager testEntityManager;

    @Autowired
    private BookRepository bookRepository;

    @Test
    public void delete() {
        // given
        String isbn = "isbn-1";
        Book book = new Book();
        book.setIsbn(isbn);
        testEntityManager.persist(book);


        Recommendation recommendation = new Recommendation();
        recommendation.setBook(book);
        testEntityManager.persist(recommendation);

        // when
        bookRepository.deleteBookByIsbn(book.getIsbn());

        // then
        assertThat(testEntityManager.find(Book.class, book.getId())).isNull();
        assertThat(testEntityManager.find(Recommendation.class, recommendation.getId())).isNull();
    }

}

@OnDelete(action=OnDeleteAction.CASCADE)如果不是从测试中调用此代码,则效果很好,但在测试中,我得到了一个例外,即建议没有被书籍删除。

此外,我尝试从为Hibernate查询记录的sql中获取任何信息,但我看不到此测试的任何删除语句。

我不想对实体使用双向链接,只想了解如何解决这个具体问题或以某种方式调试它。

共有2个答案

姜景辉
2023-03-14

需要注意的几点:

首先,据我所知@OnDelete(action=OnDeleteAction. CASCADE)只影响DDL的生成,即FK是在数据库中使用on deleteAction子句创建的。然后,您将缓存删除委托给数据库,如果您没有让Hibernate生成模式,则此注释将无效。当级联删除委托给数据库时,您将看不到Hibernate正在执行的任何SQL删除语句。

其次,在测试中,使用JPQL查询删除实体:

bookRepository。deleteBookByIsbn(book.getIsbn())

而不是使用entityManager。删除(e)(通过存储库的删除(e)方法)。

这样做的结果是,即使您要应用JPA-CacadeType。DELETE由于批量JPQL更新/删除查询不执行,因此删除操作不会级联到关联。

关于这一点,请参阅此处:

JPA删除所有实体作品奇怪

籍兴文
2023-03-14

@多通#级联

@ManyToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "book_id", nullable = false)
private Book book;

编辑1:

@ManyToOne(optional = false)
@JoinColumn(name = "book_id",
        nullable = false,
        foreignKey = @ForeignKey(
                foreignKeyDefinition = "FOREIGN KEY (book_id) REFERENCES book(id) ON DELETE CASCADE"
        )
)
private Book book;

如果您不想要双向映射并且您的模式是从您的实体创建的,则以下方法应该可以解决问题。

在从SQL创建模式的情况下,也可以在脚本中创建这样的外键。

这种方法还期望只执行一个删除查询。

 类似资料:
  • 我无法使用Hibernate JPA嵌入使cascase删除在Java EE容器管理的应用程序中工作。我们将不胜感激。我有一个实体‘公司',与其他实体有四个任何关系。当测试应用程序(使用Arquillian框架)时,我无法使级联删除工作;公司实体被删除,删除后子实体仍然存在。我读到了这里:JPA和Hibernate Cascade DELETE OneToMany不起作用,这可能是一个测试问题,所

  • 我有两个实体业务,由一个部门列表组成。 当我尝试删除一个业务实例时,我得到一个Mysql异常 无法删除或更新父行:外键约束失败(

  • 我一直在阅读一篇又一篇的帖子和文章,试图让级联删除在最新的Spring Boot版本中与JPA/Hibernate配合使用。我读过你必须使用Hibernate特定的级联,我读过你不需要。我读过它们就是不起作用,但它似乎是一个混合体。我尝试过的一切都不起作用。这种关系是双向的。 不工作: 不工作: 在删除品牌之前,除了删除税率之外,还有什么其他方法有效吗? 我的测试如下所示: 参考错误: 原因:or

  • 我试着用Twilio发一条短信,如下所示: 我得到以下错误:

  • 问题内容: 我想知道这个测试问题。我自己准备了示例并进行了测试,但是我仍然不确定答案。 具有以下内容: 据我所知,答案是: 一个。 创建两个表 虽然也有: b。 如果删除表foo2中foo_id为2的行,则表foo中id = 2的行将被自动删除 d。如果删除表foo中id = 2的行,则删除表foo2中所有foo_id = 2的行 在我的示例中,我将使用delete语法: 由于某种原因,我似乎找不

  • 有人能解释一下这是怎么回事吗?非常感谢任何帮助!